diff -u -r -N squid-3.0.STABLE20/acinclude.m4 squid-3.0.STABLE21/acinclude.m4
--- squid-3.0.STABLE20/acinclude.m4	2009-10-29 23:05:32.000000000 +1300
+++ squid-3.0.STABLE21/acinclude.m4	2009-12-22 19:50:23.000000000 +1300
@@ -69,7 +69,9 @@
 dnl
 dnl Test whether -fhuge-objects is available with this c++ compiler. gcc-29.5 series compilers need this on some platform with large objects.
 dnl
+HUGE_OBJECT_FLAG=""
 AC_DEFUN([AC_TEST_CHECKFORHUGEOBJECTS],[
+ if test "$GCC" = "yes"; then
   AC_MSG_CHECKING([whether compiler accepts -fhuge-objects])
   AC_CACHE_VAL([ac_cv_test_checkforhugeobjects],[
     ac_cv_test_checkforhugeobjects=`echo "int main(int argc, char **argv) { int foo; }" > conftest.cc
@@ -89,7 +91,6 @@
   if test "X${ac_cv_test_checkforhugeobjects}" != Xno
   then
     HUGE_OBJECT_FLAG="-fhuge-objects"
-  else
-    HUGE_OBJECT_FLAG=""
   fi
+ fi #gcc
 ]) # end of AC_DEFUN of AC_TEST_CHECKFORHUGEOBJECTS
diff -u -r -N squid-3.0.STABLE20/ChangeLog squid-3.0.STABLE21/ChangeLog
--- squid-3.0.STABLE20/ChangeLog	2009-10-29 23:05:32.000000000 +1300
+++ squid-3.0.STABLE21/ChangeLog	2009-12-22 19:50:22.000000000 +1300
@@ -1,3 +1,14 @@
+Changes to squid-3.0.STABLE21 (22 Dec 2009):
+
+	- Bug 2830: Clarify where NULL byte is in headers.
+	- Bug 2778: Linking issues using SunCC
+	- Bug 2395: FTP errors not displayed
+	- Bug 2155: Assertion failures on malformed Content-Range response headers
+	- Fix parsing and a few bugs in ACL time type
+	- Fix RFC keep-alive compliance on intercepted replies
+	- Improved security hardening on %nn parser
+	- Replace several GCC-specific code snippets.
+
 Changes to squid-3.0.STABLE20 (29 Oct 2009):
 
 	- Bug 2794: ESI parsing on FreeBSD
diff -u -r -N squid-3.0.STABLE20/configure squid-3.0.STABLE21/configure
--- squid-3.0.STABLE20/configure	2009-10-29 23:05:49.000000000 +1300
+++ squid-3.0.STABLE21/configure	2009-12-22 19:50:35.000000000 +1300
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.0.STABLE20.
+# Generated by GNU Autoconf 2.62 for Squid Web Proxy 3.0.STABLE21.
 #
 # Report bugs to <http://www.squid-cache.org/bugs/>.
 #
@@ -751,8 +751,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.0.STABLE20'
-PACKAGE_STRING='Squid Web Proxy 3.0.STABLE20'
+PACKAGE_VERSION='3.0.STABLE21'
+PACKAGE_STRING='Squid Web Proxy 3.0.STABLE21'
 PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/'
 
 ac_unique_file="src/main.cc"
@@ -1665,7 +1665,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Squid Web Proxy 3.0.STABLE20 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.0.STABLE21 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1735,7 +1735,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE20:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE21:";;
    esac
   cat <<\_ACEOF
 
@@ -2049,7 +2049,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.0.STABLE20
+Squid Web Proxy configure 3.0.STABLE21
 generated by GNU Autoconf 2.62
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -2063,7 +2063,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Squid Web Proxy $as_me 3.0.STABLE20, which was
+It was created by Squid Web Proxy $as_me 3.0.STABLE21, which was
 generated by GNU Autoconf 2.62.  Invocation command line was
 
   $ $0 $@
@@ -2781,7 +2781,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.0.STABLE20'
+ VERSION='3.0.STABLE21'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -21557,7 +21557,9 @@
 
 
 
+if test "$GCC" = "yes"; then
 
+ if test "$GCC" = "yes"; then
   { $as_echo "$as_me:$LINENO: checking whether compiler accepts -fhuge-objects" >&5
 $as_echo_n "checking whether compiler accepts -fhuge-objects... " >&6; }
   if test "${ac_cv_test_checkforhugeobjects+set}" = set; then
@@ -21584,11 +21586,11 @@
   if test "X${ac_cv_test_checkforhugeobjects}" != Xno
   then
     HUGE_OBJECT_FLAG="-fhuge-objects"
-  else
-    HUGE_OBJECT_FLAG=""
   fi
+ fi #gcc
 
-SQUID_CXXFLAGS="$SQUID_CXXFLAGS $HUGE_OBJECT_FLAG"
+       SQUID_CXXFLAGS="$SQUID_CXXFLAGS $HUGE_OBJECT_FLAG"
+fi
 
 if test -z "$PRESET_LDFLAGS"; then
     if test "$GCC" = "yes"; then
@@ -48333,7 +48335,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Squid Web Proxy $as_me 3.0.STABLE20, which was
+This file was extended by Squid Web Proxy $as_me 3.0.STABLE21, which was
 generated by GNU Autoconf 2.62.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -48386,7 +48388,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-Squid Web Proxy config.status 3.0.STABLE20
+Squid Web Proxy config.status 3.0.STABLE21
 configured by $0, generated by GNU Autoconf 2.62,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff -u -r -N squid-3.0.STABLE20/configure.in squid-3.0.STABLE21/configure.in
--- squid-3.0.STABLE20/configure.in	2009-10-29 23:05:49.000000000 +1300
+++ squid-3.0.STABLE21/configure.in	2009-12-22 19:50:34.000000000 +1300
@@ -1,7 +1,7 @@
 dnl  Configuration input file for Squid
 dnl
 dnl
-AC_INIT(Squid Web Proxy, 3.0.STABLE20, http://www.squid-cache.org/bugs/, squid)
+AC_INIT(Squid Web Proxy, 3.0.STABLE21, http://www.squid-cache.org/bugs/, squid)
 AC_PREREQ(2.52)
 AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -191,8 +191,10 @@
 AC_SUBST(SQUID_CFLAGS)
 AC_SUBST(SQUID_CXXFLAGS)
 
-AC_TEST_CHECKFORHUGEOBJECTS
-SQUID_CXXFLAGS="$SQUID_CXXFLAGS $HUGE_OBJECT_FLAG"
+if test "$GCC" = "yes"; then
+       AC_TEST_CHECKFORHUGEOBJECTS
+       SQUID_CXXFLAGS="$SQUID_CXXFLAGS $HUGE_OBJECT_FLAG"
+fi
 
 dnl Set LDFLAGS
 if test -z "$PRESET_LDFLAGS"; then
diff -u -r -N squid-3.0.STABLE20/include/config.h squid-3.0.STABLE21/include/config.h
--- squid-3.0.STABLE20/include/config.h	2009-10-29 23:05:43.000000000 +1300
+++ squid-3.0.STABLE21/include/config.h	2009-12-22 19:50:31.000000000 +1300
@@ -1,5 +1,5 @@
 /*
- * $Id: config.h,v 1.25.2.1 2008/02/25 03:41:38 amosjeffries Exp $
+ * $Id$
  *
  * AUTHOR: Duane Wessels
  *
@@ -57,83 +57,82 @@
 #endif
 
 /* define the _SQUID_TYPE_ based on a guess of the OS */
-#if defined(__sun__) || defined(__sun)	/* SUN */
-#define _SQUID_SUN_
+#if defined(__sun__) || defined(__sun) || defined(__SUNPRO_CC) || defined(__SunOS_OSversion) /* SUN */
 #if defined(__SVR4)		/* SOLARIS */
-#define _SQUID_SOLARIS_
+#define _SQUID_SOLARIS_ 1
 #else /* SUNOS */
-#define _SQUID_SUNOS_
+#define _SQUID_SUNOS_ 1
 #endif
 
 #elif defined(__hpux)		/* HP-UX - SysV-like? */
-#define _SQUID_HPUX_
-#define _SQUID_SYSV_
+#define _SQUID_HPUX_ 1
+#define _SQUID_SYSV_ 1
 
 #elif defined(__osf__)		/* OSF/1 */
-#define _SQUID_OSF_
+#define _SQUID_OSF_ 1
 
 #elif defined(__ultrix)		/* Ultrix */
-#define _SQUID_ULTRIX_
+#define _SQUID_ULTRIX_ 1
 
 #elif defined(_AIX)		/* AIX */
-#define _SQUID_AIX_
+#define _SQUID_AIX_ 1
 
 #elif defined(__linux__)	/* Linux */
-#define _SQUID_LINUX_
+#define _SQUID_LINUX_ 1
 #if USE_ASYNC_IO
-#define _SQUID_LINUX_THREADS_
+#define _SQUID_LINUX_THREADS_ 1
 #endif
 
 #elif defined(__FreeBSD__)	/* FreeBSD */
-#define _SQUID_FREEBSD_
+#define _SQUID_FREEBSD_ 1
 #if USE_ASYNC_IO && defined(LINUXTHREADS)
-#define _SQUID_LINUX_THREADS_
+#define _SQUID_LINUX_THREADS_ 1
 #endif
  
 #elif defined(__FreeBSD_kernel__)      /* GNU/kFreeBSD */
-#define _SQUID_KFREEBSD_
+#define _SQUID_KFREEBSD_ 1
 
 #elif defined(__sgi__)	|| defined(sgi) || defined(__sgi)	/* SGI */
-#define _SQUID_SGI_
+#define _SQUID_SGI_ 1
 #if !defined(_SVR4_SOURCE)
-#define _SVR4_SOURCE		/* for tempnam(3) */
+#define _SVR4_SOURCE 1		/* for tempnam(3) */
 #endif
 #if USE_ASYNC_IO
-#define _ABI_SOURCE
+#define _ABI_SOURCE 1
 #endif /* USE_ASYNC_IO */
 
 #elif defined(__NeXT__)
-#define _SQUID_NEXT_
+#define _SQUID_NEXT_ 1
 
 #elif defined(__bsdi__)
-#define _SQUID_BSDI_		/* BSD/OS */
+#define _SQUID_BSDI_ 1		/* BSD/OS */
 
 #elif defined(__NetBSD__)
-#define _SQUID_NETBSD_
+#define _SQUID_NETBSD_ 1
 
 #elif defined(__OpenBSD__)
-#define _SQUID_OPENBSD_
+#define _SQUID_OPENBSD_ 1
 
 #elif defined(__DragonFly__)
-#define _SQUID_DRAGONFLY_
+#define _SQUID_DRAGONFLY_ 1
 
 #elif defined(__CYGWIN32__)  || defined(__CYGWIN__)
-#define _SQUID_CYGWIN_
-#define _SQUID_WIN32_
+#define _SQUID_CYGWIN_ 1
+#define _SQUID_WIN32_ 1
 
 #elif defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32)
-#define _SQUID_MSWIN_
-#define _SQUID_WIN32_
+#define _SQUID_MSWIN_ 1
+#define _SQUID_WIN32_ 1
 #include "squid_mswin.h"
 
 #elif defined(__APPLE__)
-#define _SQUID_APPLE_
+#define _SQUID_APPLE_ 1
 
 #elif defined(sony_news) && defined(__svr4)
-#define _SQUID_NEWSOS6_
+#define _SQUID_NEWSOS6_ 1
 
 #elif defined(__EMX__) || defined(OS2) || defined(__OS2__)
-#define _SQUID_OS2_
+#define _SQUID_OS2_ 1
 /*
  *  FIXME: the os2 port of bash seems to have problems checking
  *  the return codes of programs in if statements.  These options
diff -u -r -N squid-3.0.STABLE20/include/profiling.h squid-3.0.STABLE21/include/profiling.h
--- squid-3.0.STABLE20/include/profiling.h	2009-10-29 23:05:43.000000000 +1300
+++ squid-3.0.STABLE21/include/profiling.h	2009-12-22 19:50:31.000000000 +1300
@@ -18,7 +18,7 @@
 #include <sys/time.h>
 #endif
 
-#if defined(__i386) || defined(__i386__)
+#if defined(__GNUC__) && ( defined(__i386) || defined(__i386__) )
 static inline hrtime_t
 get_tick(void)
 {
@@ -30,7 +30,7 @@
     /* Note that "rdtsc" is relatively slow OP and stalls the CPU pipes, so use it wisely */
 }
 
-#elif defined(__x86_64) || defined(__x86_64__)
+#elif defined(__GNUC__) && ( defined(__x86_64) || defined(__x86_64__) )
 static inline hrtime_t
 get_tick(void)
 {
@@ -41,7 +41,7 @@
     return (hrtime_t)hi << 32 | lo;
 }
 
-#elif defined(__alpha)
+#elif defined(__GNUC__) && defined(__alpha)
 static inline hrtime_t
 get_tick(void)
 {
diff -u -r -N squid-3.0.STABLE20/include/SquidNew.h squid-3.0.STABLE21/include/SquidNew.h
--- squid-3.0.STABLE20/include/SquidNew.h	2009-10-29 23:05:43.000000000 +1300
+++ squid-3.0.STABLE21/include/SquidNew.h	2009-12-22 19:50:31.000000000 +1300
@@ -34,6 +34,8 @@
 #ifndef SQUID_NEW_H
 #define SQUID_NEW_H
 
+#ifndef __SUNPRO_CC
+
 /* Any code using libstdc++ must have externally resolvable overloads
  * for void * operator new - which means in the .o for the binary,
  * or in a shared library. static libs don't propogate the symbol
@@ -57,4 +59,7 @@
 {
     xfree (address);
 }
+
+#endif /* __SUNPRO_CC */
+
 #endif /* SQUID_NEW_H */
diff -u -r -N squid-3.0.STABLE20/include/util.h squid-3.0.STABLE21/include/util.h
--- squid-3.0.STABLE20/include/util.h	2009-10-29 23:05:43.000000000 +1300
+++ squid-3.0.STABLE21/include/util.h	2009-12-22 19:50:31.000000000 +1300
@@ -83,7 +83,13 @@
  * for the extern version in squid
  */
 #ifndef _SQUID_EXTERNNEW_
-#if defined(_SQUID_SGI_) && !defined(_GNUC_)
+/*
+ * SunPro CC handles extern inline as inline, PLUS extern symbols.
+ */
+#if _SQUID_SOLARIS_ && !defined(_SQUID_EXTERNNEW_) && defined(__SUNPRO_CC)
+#define _SQUID_EXTERNNEW_ extern
+#else
+#if _SQUID_SGI_ && !defined(_GNUC_)
 /* 
  * The gcc compiler treats extern inline functions as being extern,
  * while the SGI MIPSpro compilers treat them as inline. To get equivalent
@@ -96,8 +102,9 @@
 #else
 #define _SQUID_EXTERNNEW_ extern inline
 #endif
-#endif
-#endif
+#endif /* SGI */
+#endif /* Solaris */
+#endif /* _SQUID_EXTERNNEW_ */
 #include "SquidNew.h"
 #endif
 
diff -u -r -N squid-3.0.STABLE20/include/version.h squid-3.0.STABLE21/include/version.h
--- squid-3.0.STABLE20/include/version.h	2009-10-29 23:05:49.000000000 +1300
+++ squid-3.0.STABLE21/include/version.h	2009-12-22 19:50:35.000000000 +1300
@@ -9,5 +9,5 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1256810731
+#define SQUID_RELEASE_TIME 1261464621
 #endif
diff -u -r -N squid-3.0.STABLE20/lib/libTrie/acinclude.m4 squid-3.0.STABLE21/lib/libTrie/acinclude.m4
--- squid-3.0.STABLE20/lib/libTrie/acinclude.m4	2009-10-29 23:05:44.000000000 +1300
+++ squid-3.0.STABLE21/lib/libTrie/acinclude.m4	2009-12-22 19:50:31.000000000 +1300
@@ -5,11 +5,13 @@
 dnl
 dnl Test whether -fhuge-objects is available with this c++ compiler. gcc-29.5 series compilers need this on some platform with large objects.
 dnl
+HUGE_OBJECT_FLAG=""
 AC_DEFUN([AC_TEST_CHECKFORHUGEOBJECTS],[
+ if test "$GCC" = "yes"; then
   AC_MSG_CHECKING([whether compiler accepts -fhuge-objects])
   AC_CACHE_VAL([ac_cv_test_checkforhugeobjects],[
-    ac_cv_test_checkforhugeobjects=`echo "int foo;" > conftest.cc
-${CXX} -Werror -fhuge-objects -c conftest.cc 2>/dev/null
+    ac_cv_test_checkforhugeobjects=`echo "int main(int argc, char **argv) { int foo; }" > conftest.cc
+${CXX} -Werror -fhuge-objects -o conftest.bin conftest.cc 2>/dev/null
 res=$?
 rm -f conftest.*
 echo yes
@@ -25,7 +27,7 @@
   if test "X${ac_cv_test_checkforhugeobjects}" != Xno
   then
     HUGE_OBJECT_FLAG="-fhuge-objects"
-  else
-    HUGE_OBJECT_FLAG=""
   fi
+ fi #gcc
 ]) # end of AC_DEFUN of AC_TEST_CHECKFORHUGEOBJECTS
+
diff -u -r -N squid-3.0.STABLE20/lib/libTrie/configure squid-3.0.STABLE21/lib/libTrie/configure
--- squid-3.0.STABLE20/lib/libTrie/configure	2009-10-29 23:05:44.000000000 +1300
+++ squid-3.0.STABLE21/lib/libTrie/configure	2009-12-22 19:50:31.000000000 +1300
@@ -4112,15 +4112,17 @@
    TRIE_CXXFLAGS=
 fi
 
+if test "$GCC" = "yes" ; then
 
+ if test "$GCC" = "yes"; then
   { $as_echo "$as_me:$LINENO: checking whether compiler accepts -fhuge-objects" >&5
 $as_echo_n "checking whether compiler accepts -fhuge-objects... " >&6; }
   if test "${ac_cv_test_checkforhugeobjects+set}" = set; then
   $as_echo_n "(cached) " >&6
 else
 
-    ac_cv_test_checkforhugeobjects=`echo "int foo;" > conftest.cc
-${CXX} -Werror -fhuge-objects -c conftest.cc 2>/dev/null
+    ac_cv_test_checkforhugeobjects=`echo "int main(int argc, char **argv) { int foo; }" > conftest.cc
+${CXX} -Werror -fhuge-objects -o conftest.bin conftest.cc 2>/dev/null
 res=$?
 rm -f conftest.*
 echo yes
@@ -4139,11 +4141,11 @@
   if test "X${ac_cv_test_checkforhugeobjects}" != Xno
   then
     HUGE_OBJECT_FLAG="-fhuge-objects"
-  else
-    HUGE_OBJECT_FLAG=""
   fi
+ fi #gcc
 
-TRIE_CXXFLAGS="$TRIE_CXXFLAGS $HUGE_OBJECT_FLAG"
+       TRIE_CXXFLAGS="$TRIE_CXXFLAGS $HUGE_OBJECT_FLAG"
+fi
 
 
 
diff -u -r -N squid-3.0.STABLE20/lib/libTrie/configure.in squid-3.0.STABLE21/lib/libTrie/configure.in
--- squid-3.0.STABLE20/lib/libTrie/configure.in	2009-10-29 23:05:44.000000000 +1300
+++ squid-3.0.STABLE21/lib/libTrie/configure.in	2009-12-22 19:50:31.000000000 +1300
@@ -65,8 +65,10 @@
    TRIE_CXXFLAGS=
 fi
 
-AC_TEST_CHECKFORHUGEOBJECTS
-TRIE_CXXFLAGS="$TRIE_CXXFLAGS $HUGE_OBJECT_FLAG"
+if test "$GCC" = "yes" ; then
+       AC_TEST_CHECKFORHUGEOBJECTS
+       TRIE_CXXFLAGS="$TRIE_CXXFLAGS $HUGE_OBJECT_FLAG"
+fi
 
 AC_SUBST(TRIE_CFLAGS)
 AC_SUBST(TRIE_CXXFLAGS)
diff -u -r -N squid-3.0.STABLE20/lib/md5.c squid-3.0.STABLE21/lib/md5.c
--- squid-3.0.STABLE20/lib/md5.c	2009-10-29 23:05:44.000000000 +1300
+++ squid-3.0.STABLE21/lib/md5.c	2009-12-22 19:50:31.000000000 +1300
@@ -146,7 +146,7 @@
 
     byteSwap(ctx->buf, 4);
     memcpy(digest, ctx->buf, 16);
-    memset(ctx, 0, sizeof(ctx));	/* In case it's sensitive */
+    memset(ctx, 0, sizeof(*ctx));	/* In case it's sensitive */
 }
 
 #ifndef ASM_MD5
diff -u -r -N squid-3.0.STABLE20/lib/rfc1738.c squid-3.0.STABLE21/lib/rfc1738.c
--- squid-3.0.STABLE20/lib/rfc1738.c	2009-10-29 23:05:44.000000000 +1300
+++ squid-3.0.STABLE21/lib/rfc1738.c	2009-12-22 19:50:31.000000000 +1300
@@ -179,33 +179,44 @@
  *  rfc1738_unescape() - Converts escaped characters (%xy numbers) in 
  *  given the string.  %% is a %. %ab is the 8-bit hexadecimal number "ab"
  */
+static inline int
+fromhex(char ch)
+{
+    if (ch >= '0' && ch <= '9')
+        return ch - '0';
+    if (ch >= 'a' && ch <= 'f')
+        return ch - 'a' + 10;
+    if (ch >= 'A' && ch <= 'F')
+        return ch - 'A' + 10;
+    return -1;
+}
+
 void
 rfc1738_unescape(char *s)
 {
-    char hexnum[3];
     int i, j;			/* i is write, j is read */
-    unsigned int x;
     for (i = j = 0; s[j]; i++, j++) {
-	s[i] = s[j];
-	if (s[i] != '%')
-	    continue;
-	if (s[j + 1] == '%') {	/* %% case */
-	    j++;
-	    continue;
-	}
-	if (s[j + 1] && s[j + 2]) {
-	    if (s[j + 1] == '0' && s[j + 2] == '0') {	/* %00 case */
-		j += 2;
-		continue;
-	    }
-	    hexnum[0] = s[j + 1];
-	    hexnum[1] = s[j + 2];
-	    hexnum[2] = '\0';
-	    if (1 == sscanf(hexnum, "%x", &x)) {
-		s[i] = (char) (0x0ff & x);
-		j += 2;
-	    }
-	}
+        s[i] = s[j];
+        if (s[j] != '%') {
+            /* normal case, nothing more to do */
+        } else if (s[j + 1] == '%') {	/* %% case */
+            j++;		/* Skip % */
+        } else {
+            /* decode */
+            char v1, v2;
+            int x;
+            v1 = fromhex(s[j + 1]);
+            if (v1 < 0)
+                continue;  /* non-hex or \0 */
+            v2 = fromhex(s[j + 2]);
+            if (v2 < 0)
+                continue;  /* non-hex or \0 */
+            x = v1 << 4 | v2;
+            if (x > 0 && x <= 255) {
+                s[i] = x;
+                j += 2;
+            }
+        }
     }
     s[i] = '\0';
 }
diff -u -r -N squid-3.0.STABLE20/RELEASENOTES.html squid-3.0.STABLE21/RELEASENOTES.html
--- squid-3.0.STABLE20/RELEASENOTES.html	2009-10-29 23:06:44.000000000 +1300
+++ squid-3.0.STABLE21/RELEASENOTES.html	2009-12-22 19:52:08.000000000 +1300
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.65">
- <TITLE>Squid 3.0.STABLE20 release notes</TITLE>
+ <TITLE>Squid 3.0.STABLE21 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.0.STABLE20 release notes</H1>
+<H1>Squid 3.0.STABLE21 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -60,7 +60,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.0.STABLE20.</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.0.STABLE21.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.0/">http://www.squid-cache.org/Versions/v3/3.0/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
diff -u -r -N squid-3.0.STABLE20/src/ACLTimeData.cc squid-3.0.STABLE21/src/ACLTimeData.cc
--- squid-3.0.STABLE20/src/ACLTimeData.cc	2009-10-29 23:05:45.000000000 +1300
+++ squid-3.0.STABLE21/src/ACLTimeData.cc	2009-12-22 19:50:32.000000000 +1300
@@ -127,7 +127,7 @@
 ACLTimeData::parse()
 {
     ACLTimeData **Tail;
-    long weekbits = 0;
+    long parsed_weekbits = 0;
 
     for (Tail = &next; *Tail; Tail = &((*Tail)->next))
 
@@ -146,35 +146,35 @@
                 switch (*t++) {
 
                 case 'S':
-                    weekbits |= ACL_SUNDAY;
+                    parsed_weekbits |= ACL_SUNDAY;
                     break;
 
                 case 'M':
-                    weekbits |= ACL_MONDAY;
+                    parsed_weekbits |= ACL_MONDAY;
                     break;
 
                 case 'T':
-                    weekbits |= ACL_TUESDAY;
+                    parsed_weekbits |= ACL_TUESDAY;
                     break;
 
                 case 'W':
-                    weekbits |= ACL_WEDNESDAY;
+                    parsed_weekbits |= ACL_WEDNESDAY;
                     break;
 
                 case 'H':
-                    weekbits |= ACL_THURSDAY;
+                    parsed_weekbits |= ACL_THURSDAY;
                     break;
 
                 case 'F':
-                    weekbits |= ACL_FRIDAY;
+                    parsed_weekbits |= ACL_FRIDAY;
                     break;
 
                 case 'A':
-                    weekbits |= ACL_SATURDAY;
+                    parsed_weekbits |= ACL_SATURDAY;
                     break;
 
                 case 'D':
-                    weekbits |= ACL_WEEKDAYS;
+                    parsed_weekbits |= ACL_WEEKDAYS;
                     break;
 
                 case '-':
@@ -201,7 +201,7 @@
                 return;
             }
 
-            if ((weekbits == 0) && (start == 0) && (stop == 0))
+            if ((parsed_weekbits == 0) && (start == 0) && (stop == 0))
                 q = this;
             else
                 q = new ACLTimeData;
@@ -210,9 +210,9 @@
 
             q->stop = h2 * 60 + m2;
 
-            q->weekbits = weekbits;
+            q->weekbits = parsed_weekbits;
 
-            weekbits = 0;
+            parsed_weekbits = 0;
 
             if (q->start > q->stop) {
                 debugs(28, 0, "aclParseTimeSpec: Reversed time range");
@@ -234,23 +234,18 @@
         }
     }
 
-    if (weekbits) {
+    if (parsed_weekbits) {
 
-        if ((weekbits == 0) && (start == 0) && (stop == 0))
-            q = this;
-        else
-            q = new ACLTimeData;
+        q = new ACLTimeData;
 
         q->start = 0 * 60 + 0;
 
         q->stop =  24 * 60 + 0;
 
-        q->weekbits = weekbits;
+        q->weekbits = parsed_weekbits;
 
-        if (q != this) {
-            *(Tail) = q;
-            Tail = &q->next;
-        }
+        *(Tail) = q;
+        Tail = &q->next;
     }
 }
 
diff -u -r -N squid-3.0.STABLE20/src/asn.cc squid-3.0.STABLE21/src/asn.cc
--- squid-3.0.STABLE20/src/asn.cc	2009-10-29 23:05:46.000000000 +1300
+++ squid-3.0.STABLE21/src/asn.cc	2009-12-22 19:50:32.000000000 +1300
@@ -110,9 +110,17 @@
 
 static STCB asHandleReply;
 
-static int destroyRadixNode(struct squid_radix_node *rn, void *w);
 
-static int printRadixNode(struct squid_radix_node *rn, void *sentry);
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+    static int destroyRadixNode(struct squid_radix_node *rn, void *w);
+    static int printRadixNode(struct squid_radix_node *rn, void *sentry);
+
+#if defined(__cplusplus)
+}
+#endif
 
 void asnAclInitialize(ACL * acls);
 
diff -u -r -N squid-3.0.STABLE20/src/cbdata.h squid-3.0.STABLE21/src/cbdata.h
--- squid-3.0.STABLE20/src/cbdata.h	2009-10-29 23:05:47.000000000 +1300
+++ squid-3.0.STABLE21/src/cbdata.h	2009-12-22 19:50:33.000000000 +1300
@@ -73,6 +73,7 @@
 #define cbdataInternalUnlock(a)		cbdataInternalUnlockDbg(a,__FILE__,__LINE__)
 #define cbdataReferenceValidDone(var, ptr) cbdataInternalReferenceDoneValidDbg((void **)&(var), (ptr), __FILE__,__LINE__)
 #define CBDATA_CLASS2(type)	\
+	private: \
 	static cbdata_type CBDATA_##type; \
 	public: \
 		void *operator new(size_t size) { \
@@ -83,8 +84,8 @@
   		void operator delete (void *address) { \
 		  if (address) cbdataInternalFreeDbg(address,__FILE__,__LINE__); \
 		} \
-	private:
 #else
+#else /* CBDATA_DEBUG */
 #define cbdataAlloc(type) ((type *)cbdataInternalAlloc(CBDATA_##type))
 #define cbdataFree(var)		do {if (var) {cbdataInternalFree(var); var = NULL;}} while(0)
 #define cbdataReferenceValidDone(var, ptr) cbdataInternalReferenceDoneValid((void **)&(var), (ptr))
diff -u -r -N squid-3.0.STABLE20/src/client_side_reply.cc squid-3.0.STABLE21/src/client_side_reply.cc
--- squid-3.0.STABLE20/src/client_side_reply.cc	2009-10-29 23:05:47.000000000 +1300
+++ squid-3.0.STABLE21/src/client_side_reply.cc	2009-12-22 19:50:33.000000000 +1300
@@ -1302,8 +1302,8 @@
         hdr->putStr(HDR_VIA, strVia.buf());
     }
     /* Signal keep-alive if needed */
-    hdr->putStr(http->flags.accel ? HDR_CONNECTION : HDR_PROXY_CONNECTION,
-                request->flags.proxy_keepalive ? "keep-alive" : "close");
+    hdr->putStr( (http->flags.accel || http->flags.transparent)? HDR_CONNECTION : HDR_PROXY_CONNECTION,
+                 request->flags.proxy_keepalive ? "keep-alive" : "close");
 
 #if ADD_X_REQUEST_URI
     /*
diff -u -r -N squid-3.0.STABLE20/src/dnsserver.cc squid-3.0.STABLE21/src/dnsserver.cc
--- squid-3.0.STABLE20/src/dnsserver.cc	2009-10-29 23:05:47.000000000 +1300
+++ squid-3.0.STABLE21/src/dnsserver.cc	2009-12-22 19:50:33.000000000 +1300
@@ -276,11 +276,10 @@
     char request[512];
     char *t = NULL;
     int c;
-#if HAVE_RES_INIT
-
     int opt_s = 0;
-#if HAVE_RES_NSADDR_LIST || HAVE_RES_NS_LIST
 
+#if HAVE_RES_INIT
+#if HAVE_RES_NSADDR_LIST || HAVE_RES_NS_LIST
     extern char *optarg;
 #endif
 #endif
@@ -288,7 +287,6 @@
     safe_inet_addr("255.255.255.255", &no_addr);
 
 #if HAVE_RES_INIT
-
     res_init();
 #ifdef RES_DEFAULT
 
diff -u -r -N squid-3.0.STABLE20/src/ftp.cc squid-3.0.STABLE21/src/ftp.cc
--- squid-3.0.STABLE20/src/ftp.cc	2009-10-29 23:05:47.000000000 +1300
+++ squid-3.0.STABLE21/src/ftp.cc	2009-12-22 19:50:33.000000000 +1300
@@ -3032,10 +3032,11 @@
 void
 FtpStateData::failedErrorMessage(err_type error, int xerrno)
 {
-    ErrorState *err;
+    ErrorState *ftperr;
     const char *command, *reply;
+
     /* Translate FTP errors into HTTP errors */
-    err = NULL;
+    ftperr = NULL;
 
     switch (error) {
 
@@ -3049,12 +3050,12 @@
 
             if (ctrl.replycode > 500)
                 if (password_url)
-                    err = errorCon(ERR_FTP_FORBIDDEN, HTTP_FORBIDDEN, fwd->request);
+                    ftperr = errorCon(ERR_FTP_FORBIDDEN, HTTP_FORBIDDEN, fwd->request);
                 else
-                    err = errorCon(ERR_FTP_FORBIDDEN, HTTP_UNAUTHORIZED, fwd->request);
+                    ftperr = errorCon(ERR_FTP_FORBIDDEN, HTTP_UNAUTHORIZED, fwd->request);
 
             else if (ctrl.replycode == 421)
-                err = errorCon(ERR_FTP_UNAVAILABLE, HTTP_SERVICE_UNAVAILABLE, fwd->request);
+                ftperr = errorCon(ERR_FTP_UNAVAILABLE, HTTP_SERVICE_UNAVAILABLE, fwd->request);
 
             break;
 
@@ -3062,7 +3063,7 @@
 
         case SENT_RETR:
             if (ctrl.replycode == 550)
-                err = errorCon(ERR_FTP_NOT_FOUND, HTTP_NOT_FOUND, fwd->request);
+                ftperr = errorCon(ERR_FTP_NOT_FOUND, HTTP_NOT_FOUND, fwd->request);
 
             break;
 
@@ -3073,20 +3074,20 @@
         break;
 
     case ERR_READ_TIMEOUT:
-        err = errorCon(error, HTTP_GATEWAY_TIMEOUT, fwd->request);
+        ftperr = errorCon(error, HTTP_GATEWAY_TIMEOUT, fwd->request);
         break;
 
     default:
-        err = errorCon(error, HTTP_BAD_GATEWAY, fwd->request);
+        ftperr = errorCon(error, HTTP_BAD_GATEWAY, fwd->request);
         break;
     }
 
-    if (err == NULL)
-        err = errorCon(ERR_FTP_FAILURE, HTTP_BAD_GATEWAY, fwd->request);
+    if (ftperr == NULL)
+        ftperr = errorCon(ERR_FTP_FAILURE, HTTP_BAD_GATEWAY, fwd->request);
 
-    err->xerrno = xerrno;
+    ftperr->xerrno = xerrno;
 
-    err->ftp.server_msg = ctrl.message;
+    ftperr->ftp.server_msg = ctrl.message;
 
     ctrl.message = NULL;
 
@@ -3104,12 +3105,13 @@
         reply = ctrl.last_reply;
 
     if (command)
-        err->ftp.request = xstrdup(command);
+        ftperr->ftp.request = xstrdup(command);
 
     if (reply)
-        err->ftp.reply = xstrdup(reply);
+        ftperr->ftp.reply = xstrdup(reply);
 
-    fwd->fail(err);
+    entry->replaceHttpReply( errorBuildReply(ftperr) );
+    errorStateFree(ftperr);
 }
 
 static void
@@ -3150,7 +3152,8 @@
     else
         err->ftp.reply = xstrdup("");
 
-    errorAppendEntry(ftpState->entry, err);
+    ftpState->entry->replaceHttpReply( errorBuildReply(err) );
+    errorStateFree(err);
 
     ftpSendQuit(ftpState);
 }
diff -u -r -N squid-3.0.STABLE20/src/HttpHdrContRange.cc squid-3.0.STABLE21/src/HttpHdrContRange.cc
--- squid-3.0.STABLE20/src/HttpHdrContRange.cc	2009-10-29 23:05:45.000000000 +1300
+++ squid-3.0.STABLE21/src/HttpHdrContRange.cc	2009-12-22 19:50:32.000000000 +1300
@@ -84,22 +84,34 @@
     if (!httpHeaderParseOffset(field, &spec->offset))
         return 0;
 
+    /* Additional check for BUG2155 - there MUST BE first-byte-pos and it MUST be positive*/
+    if (spec->offset < 0) {
+        debugs(68, 2, "invalid (no first-byte-pos or it is negative) resp-range-spec near: '" << field << "'");
+        return 0;
+    }
+
     p++;
 
     /* do we have last-pos ? */
-    if (p - field < flen) {
-        int64_t last_pos;
+    if (p - field >= flen) {
+        debugs(68, 2, "invalid (no last-byte-pos) resp-range-spec near: '" << field << "'");
+        return 0;
+    }
+
+    int64_t last_pos;
 
-        if (!httpHeaderParseOffset(p, &last_pos))
-            return 0;
+    if (!httpHeaderParseOffset(p, &last_pos))
+        return 0;
 
-        spec->length = size_diff(last_pos + 1, spec->offset);
-        /* Ensure typecast is safe */
-        assert (spec->length >= 0);
+    if (last_pos < spec->offset) {
+        debugs(68, 2, "invalid (negative last-byte-pos) resp-range-spec near: '" << field << "'");
+        return 0;
     }
 
+    spec->length = size_diff(last_pos + 1, spec->offset);
+
     /* we managed to parse, check if the result makes sence */
-    if (known_spec(spec->length) && spec->length == 0) {
+    if (spec->length <= 0) {
         debugs(68, 2, "invalid range (" << spec->offset << " += " <<
                (long int) spec->length << ") in resp-range-spec near: '" << field << "'");
         return 0;
@@ -176,6 +188,14 @@
         range->elength = range_spec_unknown;
     else if (!httpHeaderParseOffset(p, &range->elength))
         return 0;
+    else if (range->elength <= 0) {
+        /* Additional paranoidal check for BUG2155 - entity-length MUST be > 0 */
+        debugs(68, 2, "invalid (entity-length is negative) content-range-spec near: '" << str << "'");
+        return 0;
+    } else if (known_spec(range->spec.length) && range->elength < (range->spec.offset + range->spec.length)) {
+        debugs(68, 2, "invalid (range is outside entity-length) content-range-spec near: '" << str << "'");
+        return 0;
+    }
 
         debugs(68, 8, "parsed content-range field: " <<
                (long int) range->spec.offset << "-" <<
diff -u -r -N squid-3.0.STABLE20/src/HttpHeader.cc squid-3.0.STABLE21/src/HttpHeader.cc
--- squid-3.0.STABLE20/src/HttpHeader.cc	2009-10-29 23:05:45.000000000 +1300
+++ squid-3.0.STABLE21/src/HttpHeader.cc	2009-12-22 19:50:32.000000000 +1300
@@ -504,9 +504,10 @@
     debugs(55, 7, "parsing hdr: (" << this << ")" << std::endl << getStringPrefix(header_start, header_end));
     HttpHeaderStats[owner].parsedCount++;
 
-    if (memchr(header_start, '\0', header_end - header_start)) {
+    char *nulpos;
+    if ((nulpos = (char*)memchr(header_start, '\0', header_end - header_start))) {
         debugs(55, 1, "WARNING: HTTP header contains NULL characters {" << 
-                      getStringPrefix(header_start, header_end) << "}");
+               getStringPrefix(header_start, nulpos) << "}\nNULL\n{" << getStringPrefix(nulpos+1, header_end) << "}");
         goto reset;
     }
 
diff -u -r -N squid-3.0.STABLE20/src/SquidNew.cc squid-3.0.STABLE21/src/SquidNew.cc
--- squid-3.0.STABLE20/src/SquidNew.cc	2009-10-29 23:05:46.000000000 +1300
+++ squid-3.0.STABLE21/src/SquidNew.cc	2009-12-22 19:50:32.000000000 +1300
@@ -33,5 +33,28 @@
  *
  */
 
-#define _SQUID_EXTERNNEW_
+/* #define _SQUID_EXTERNNEW_ */ /* Why? kinkie */
 #include "squid.h"
+
+
+#ifdef __SUNPRO_CC
+
+#include <new>
+void *operator new(size_t size) throw (std::bad_alloc)
+{
+    return xmalloc(size);
+}
+void operator delete (void *address) throw()
+{
+    xfree (address);
+}
+void *operator new[] (size_t size) throw (std::bad_alloc)
+{
+    return xmalloc(size);
+}
+void operator delete[] (void *address) throw()
+{
+    xfree (address);
+}
+
+#endif /* __SUNPRO_CC */
