diff -u -r -N squid-3.3.0.1/ChangeLog squid-3.3.0.2/ChangeLog
--- squid-3.3.0.1/ChangeLog	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/ChangeLog	2012-12-02 21:30:11.000000000 +1300
@@ -1,3 +1,9 @@
+Changes to squid-3.3.0.2 (03 Dec 2012):
+
+	- Support matching empty header field values using req_header and rep_header
+	- ... and some minor code polish and input vaidations
+	- ... and all changes from squid 3.2.4
+
 Changes to squid-3.3.0.1 (21 Oct 2012):
 
 	- Bug 3610: Add peername_regex ACL
@@ -17,6 +23,18 @@
 	- ... and many compile error fixes
 	- ... and a very large amount of code polish for faster compilation
 
+Changes to squid-3.2.4 (03 Dec 2012):
+
+	- Ported: urllogin ACL from squid 2.7
+	- Bug 3688: Lots of Orphan Comm:Connections to ICAP server
+	- Bug 3677: Port un-pinning logic changes from squid 3.3
+	- Bug 3405: ssl_crtd crashes failing to remove certificate
+	- ... and major bugs fixed in squid 3.1.22
+	- Fix accept_filter on Linux
+	- Remove 'Bungled' warning on missing component directives
+	- ... and many buffer and memory leak issues in the bundled helpers
+	- ... and a small amount of code polishing
+
 Changes to squid-3.2.3 (21 Oct 2012):
 
 	- Regression: SMP crashes on startup with workers > 1
@@ -454,6 +472,14 @@
 	- ... and a great many testing improvements
 	- ... and many documentation updates
 
+Changes to squid-3.1.22 (03 Dec 2012):
+
+	- Bug 3685: Squid hangs in Delay Pools ClassCBucket::update
+	- Bug 3659: read_timeout problem with HTTPS
+	- Bug 3654: Fix IPv6 enabled squidclient
+	- Bug 3189: AIO thread race on pipe() initialization
+	- cachemgr.cgi: Memory Leaks and DoS Vulnerability
+
 Changes to squid-3.1.21 (23 Sep 2012):
 
 	- Bug 3622: peerClearRRStart scheduling multiple events
diff -u -r -N squid-3.3.0.1/configure squid-3.3.0.2/configure
--- squid-3.3.0.1/configure	2012-10-21 00:33:47.000000000 +1300
+++ squid-3.3.0.2/configure	2012-12-02 21:31:05.000000000 +1300
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.3.0.1.
+# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.3.0.2.
 #
 # Report bugs to <http://www.squid-cache.org/bugs/>.
 #
@@ -575,8 +575,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.3.0.1'
-PACKAGE_STRING='Squid Web Proxy 3.3.0.1'
+PACKAGE_VERSION='3.3.0.2'
+PACKAGE_STRING='Squid Web Proxy 3.3.0.2'
 PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/'
 PACKAGE_URL=''
 
@@ -1570,7 +1570,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.3.0.1 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.3.0.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1640,7 +1640,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 3.3.0.1:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.3.0.2:";;
    esac
   cat <<\_ACEOF
 
@@ -2014,7 +2014,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.3.0.1
+Squid Web Proxy configure 3.3.0.2
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -3110,7 +3110,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.3.0.1, which was
+It was created by Squid Web Proxy $as_me 3.3.0.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3929,7 +3929,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.3.0.1'
+ VERSION='3.3.0.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -31296,7 +31296,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.3.0.1, which was
+This file was extended by Squid Web Proxy $as_me 3.3.0.2, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -31362,7 +31362,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-Squid Web Proxy config.status 3.3.0.1
+Squid Web Proxy config.status 3.3.0.2
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff -u -r -N squid-3.3.0.1/configure.ac squid-3.3.0.2/configure.ac
--- squid-3.3.0.1/configure.ac	2012-10-21 00:33:47.000000000 +1300
+++ squid-3.3.0.2/configure.ac	2012-12-02 21:31:05.000000000 +1300
@@ -1,4 +1,4 @@
-AC_INIT([Squid Web Proxy],[3.3.0.1],[http://www.squid-cache.org/bugs/],[squid])
+AC_INIT([Squid Web Proxy],[3.3.0.2],[http://www.squid-cache.org/bugs/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/DB/basic_db_auth.8 squid-3.3.0.2/helpers/basic_auth/DB/basic_db_auth.8
--- squid-3.3.0.1/helpers/basic_auth/DB/basic_db_auth.8	2012-10-21 01:02:16.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/DB/basic_db_auth.8	2012-12-02 21:48:01.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_DB_AUTH 1"
-.TH BASIC_DB_AUTH 1 "2012-10-20" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 1 "2012-12-02" "perl v5.10.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/MSNT/confload.cc squid-3.3.0.2/helpers/basic_auth/MSNT/confload.cc
--- squid-3.3.0.1/helpers/basic_auth/MSNT/confload.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/MSNT/confload.cc	2012-12-02 21:30:11.000000000 +1300
@@ -85,6 +85,7 @@
         Confbuf[2048] = '\0';
         ProcessLine(Confbuf);
     }
+    fclose(ConfigFile);
 
     /*
      * Check that at least one server is being queried. Report error if not.
@@ -95,7 +96,6 @@
         syslog(LOG_ERR, "OpenConfigFile: No servers set in %s. At least one is needed.", CONFIGFILE);
         return 1;
     }
-    fclose(ConfigFile);
     return 0;
 }
 
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/MSNT/usersfile.cc squid-3.3.0.2/helpers/basic_auth/MSNT/usersfile.cc
--- squid-3.3.0.1/helpers/basic_auth/MSNT/usersfile.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/MSNT/usersfile.cc	2012-12-02 21:30:11.000000000 +1300
@@ -83,14 +83,17 @@
      * Clear the allowed user string. Return. */
     if (fstat(fileno(fp), &FileBuf) < 0) {
         syslog(LOG_ERR, "%s: %s", path, strerror(errno));
+        fclose(fp);
         return 1;
     }
     /* If it exists, save the modification time and size */
     uf->LMT = FileBuf.st_mtime;
 
     /* Handle the special case of a zero length file */
-    if (FileBuf.st_size == 0)
+    if (FileBuf.st_size == 0) {
+        fclose(fp);
         return 0;
+    }
 
     /*
      * Read the file into memory
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/NCSA/basic_ncsa_auth.cc squid-3.3.0.2/helpers/basic_auth/NCSA/basic_ncsa_auth.cc
--- squid-3.3.0.1/helpers/basic_auth/NCSA/basic_ncsa_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/NCSA/basic_ncsa_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -65,7 +65,7 @@
 read_passwd_file(const char *passwdfile)
 {
     FILE *f;
-    char buf[8192];
+    char buf[HELPER_INPUT_BUFFER];
     user_data *u;
     char *user;
     char *passwd;
@@ -84,11 +84,18 @@
         fprintf(stderr, "FATAL: %s: %s\n", passwdfile, xstrerror());
         exit(1);
     }
-    while (fgets(buf, 8192, f) != NULL) {
+    unsigned int lineCount = 0;
+    buf[HELPER_INPUT_BUFFER-1] = '\0';
+    while (fgets(buf, sizeof(buf)-1, f) != NULL) {
+        ++lineCount;
         if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') ||
                 (buf[0] == '\n'))
             continue;
         user = strtok(buf, ":\n\r");
+        if (user == NULL) {
+            fprintf(stderr, "ERROR: Missing user name at %s line %d\n", passwdfile, lineCount);
+            continue;
+        }
         passwd = strtok(NULL, ":\n\r");
         if ((strlen(user) > 0) && passwd) {
             u = static_cast<user_data*>(xmalloc(sizeof(*u)));
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/PAM/basic_pam_auth.cc squid-3.3.0.2/helpers/basic_auth/PAM/basic_pam_auth.cc
--- squid-3.3.0.1/helpers/basic_auth/PAM/basic_pam_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/PAM/basic_pam_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -258,8 +258,7 @@
         /* Authentication */
         retval = PAM_SUCCESS;
         if (ttl != 0) {
-            if (retval == PAM_SUCCESS)
-                retval = pam_set_item(pamh, PAM_USER, user);
+            retval = pam_set_item(pamh, PAM_USER, user);
             if (retval == PAM_SUCCESS)
                 retval = pam_set_item(pamh, PAM_CONV, &conv);
         }
@@ -276,12 +275,11 @@
         /* cleanup */
         retval = PAM_SUCCESS;
 #if defined(PAM_AUTHTOK)
-        if (ttl != 0) {
-            if (retval == PAM_SUCCESS)
-                retval = pam_set_item(pamh, PAM_AUTHTOK, NULL);
+        if (ttl != 0 && pamh) {
+            retval = pam_set_item(pamh, PAM_AUTHTOK, NULL);
         }
 #endif
-        if (ttl == 0 || retval != PAM_SUCCESS) {
+        if (pamh && (ttl == 0 || retval != PAM_SUCCESS)) {
             retval = pam_end(pamh, retval);
             if (retval != PAM_SUCCESS) {
                 debug("WARNING: failed to release PAM authenticator\n");
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/RADIUS/basic_radius_auth.cc squid-3.3.0.2/helpers/basic_auth/RADIUS/basic_radius_auth.cc
--- squid-3.3.0.1/helpers/basic_auth/RADIUS/basic_radius_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/RADIUS/basic_radius_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -321,7 +321,7 @@
         length = MAXPWNAM;
     }
     *ptr = length + 2;
-    ++ptr;
+    ptr = (unsigned char*)send_buffer + sizeof(AUTH_HDR);
     memcpy(ptr, username, length);
     ptr += length;
     total_length += length + 2;
@@ -424,7 +424,13 @@
          *    Send the request we've built.
          */
         gettimeofday(&sent, NULL);
-        send(socket_fd, (char *) auth, total_length, 0);
+        if (send(socket_fd, (char *) auth, total_length, 0) < 0) {
+            // EAGAIN is expected at high traffic, just retry
+            // TODO: block/sleep a few ms to let the apparently full buffer drain ?
+            if (errno != EAGAIN && errno != EWOULDBLOCK)
+                fprintf(stderr,"ERROR: RADIUS send() failure: %s\n", xstrerror());
+            continue;
+        }
         while ((time_spent = time_since(&sent)) < 1000000) {
             struct timeval tv;
             int rc, len;
@@ -488,16 +494,20 @@
             cfname = optarg;
             break;
         case 'h':
-            strcpy(server, optarg);
+            strncpy(server, optarg, sizeof(server)-1);
+            server[sizeof(server)-1] = '\0';
             break;
         case 'p':
-            strcpy(svc_name, optarg);
+            strncpy(svc_name, optarg, sizeof(svc_name)-1);
+            svc_name[sizeof(svc_name)-1] = '\0';
             break;
         case 'w':
-            strcpy(secretkey, optarg);
+            strncpy(secretkey, optarg, sizeof(secretkey)-1);
+            secretkey[sizeof(secretkey)-1] = '\0';
             break;
         case 'i':
-            strcpy(identifier, optarg);
+            strncpy(identifier, optarg, sizeof(identifier)-1);
+            identifier[sizeof(identifier)-1] = '\0';
             break;
         case 't':
             retries = atoi(optarg);
@@ -565,7 +575,10 @@
         exit(1);
     }
 #ifdef O_NONBLOCK
-    fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
+    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK) < 0) {
+        fprintf(stderr,"%s| ERROR: fcntl() failure: %s\n", argv[0], xstrerror());
+        exit(1);
+    }
 #endif
     nas_ipaddr = ntohl(salocal.sin_addr.s_addr);
     while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
diff -u -r -N squid-3.3.0.1/helpers/basic_auth/SMB/basic_smb_auth.cc squid-3.3.0.2/helpers/basic_auth/SMB/basic_smb_auth.cc
--- squid-3.3.0.1/helpers/basic_auth/SMB/basic_smb_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/basic_auth/SMB/basic_smb_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -82,7 +82,11 @@
     int i = 0;
 
     for (t = s; *t != '\0'; ++t) {
-        if (i > HELPER_INPUT_BUFFER-2) {
+        /*
+         * NP: The shell escaping permits 'i' to jump up to 2 octets per loop,
+         *     so ensure we have at least 3 free.
+         */
+        if (i > HELPER_INPUT_BUFFER-3) {
             buf[i] = '\0';
             (void) fputs(buf, p);
             i = 0;
diff -u -r -N squid-3.3.0.1/helpers/digest_auth/eDirectory/ldap_backend.cc squid-3.3.0.2/helpers/digest_auth/eDirectory/ldap_backend.cc
--- squid-3.3.0.1/helpers/digest_auth/eDirectory/ldap_backend.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/digest_auth/eDirectory/ldap_backend.cc	2012-12-02 21:30:11.000000000 +1300
@@ -286,7 +286,8 @@
             value = values;
             while (*value) {
                 if (encrpass) {
-                    if (strcmp(strtok(*value, delimiter), realm) == 0) {
+                    const char *t = strtok(*value, delimiter);
+                    if (t && strcmp(t, realm) == 0) {
                         password = strtok(NULL, delimiter);
                         break;
                     }
diff -u -r -N squid-3.3.0.1/helpers/digest_auth/file/text_backend.cc squid-3.3.0.2/helpers/digest_auth/file/text_backend.cc
--- squid-3.3.0.1/helpers/digest_auth/file/text_backend.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/digest_auth/file/text_backend.cc	2012-12-02 21:30:11.000000000 +1300
@@ -56,7 +56,6 @@
 static void
 read_passwd_file(const char *passwordFile, int isHa1Mode)
 {
-    FILE *f;
     char buf[8192];
     user_data *u;
     char *user;
@@ -73,12 +72,22 @@
         fprintf(stderr, "digest_file_auth: cannot create hash table\n");
         exit(1);
     }
-    f = fopen(passwordFile, "r");
-    while (fgets(buf, 8192, f) != NULL) {
+    FILE *f = fopen(passwordFile, "r");
+    if (!f) {
+        fprintf(stderr, "digest_file_auth: cannot open password file: %s\n", xstrerror());
+        exit(1);
+    }
+    unsigned int lineCount = 0;
+    while (fgets(buf, sizeof(buf), f) != NULL) {
+        ++lineCount;
         if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') ||
                 (buf[0] == '\n'))
             continue;
         user = strtok(buf, ":\n");
+        if (!user) {
+            fprintf(stderr, "digest_file_auth: missing user name at line %u in '%s'\n", lineCount, passwordFile);
+            continue;
+        }
         realm = strtok(NULL, ":\n");
         passwd = strtok(NULL, ":\n");
         if (!passwd) {
diff -u -r -N squid-3.3.0.1/helpers/digest_auth/LDAP/ldap_backend.cc squid-3.3.0.2/helpers/digest_auth/LDAP/ldap_backend.cc
--- squid-3.3.0.1/helpers/digest_auth/LDAP/ldap_backend.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/digest_auth/LDAP/ldap_backend.cc	2012-12-02 21:30:11.000000000 +1300
@@ -263,7 +263,8 @@
             value = values;
             while (*value) {
                 if (encrpass) {
-                    if (strcmp(strtok(*value, delimiter), realm) == 0) {
+                    const char *t = strtok(*value, delimiter);
+                    if (t && strcmp(t, realm) == 0) {
                         password = strtok(NULL, delimiter);
                         break;
                     }
diff -u -r -N squid-3.3.0.1/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc squid-3.3.0.2/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc
--- squid-3.3.0.1/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.cc	2012-12-02 21:30:11.000000000 +1300
@@ -1178,10 +1178,7 @@
     if (l->lm != NULL)
         ldap_msgfree(l->lm);						/* Make sure l->lm is empty */
 
-    if (filter == NULL)							/* if filter is NULL, then return ALL networkAddress */
-        xstrncpy(ft, "(&(objectClass=User)(networkAddress=*))", sizeof(ft));
-    else
-        xstrncpy(ft, filter, sizeof(ft));
+    xstrncpy(ft, filter, sizeof(ft));
 
     /* We have a binded connection, with a free l->lm, so let's get this done */
     switch (scope) {
@@ -1408,14 +1405,6 @@
         ldap_value_free_len(l->val);
         l->val = NULL;
     }
-    if (ber != NULL) {
-        ldap_value_free_len(ber);
-        ber = NULL;
-    }
-    if (ent != NULL) {
-        ldap_msgfree(ent);
-        ent = NULL;
-    }
     if (l->lm != NULL) {
         ldap_msgfree(l->lm);
         l->lm = NULL;
diff -u -r -N squid-3.3.0.1/helpers/external_acl/file_userip/ext_file_userip_acl.cc squid-3.3.0.2/helpers/external_acl/file_userip/ext_file_userip_acl.cc
--- squid-3.3.0.1/helpers/external_acl/file_userip/ext_file_userip_acl.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/external_acl/file_userip/ext_file_userip_acl.cc	2012-12-02 21:30:11.000000000 +1300
@@ -75,9 +75,6 @@
 						   linked list */
     char line[DICT_BUFFER_SIZE]; /* the buffer for the lines read
 				   from the dict file */
-    char *cp;			/* a char pointer used to parse
-				   each line */
-    char *username;		/* for the username */
     char *tmpbuf;			/* for the address before the
 				   bitwise AND */
 
@@ -85,17 +82,28 @@
     first_entry = (struct ip_user_dict*)malloc(sizeof(struct ip_user_dict));
     current_entry = first_entry;
 
-    while ((cp = fgets (line, DICT_BUFFER_SIZE, FH)) != NULL) {
+    unsigned int lineCount = 0;
+    while (fgets(line, sizeof(line), FH) != NULL) {
+        ++lineCount;
         if (line[0] == '#') {
             continue;
         }
+
+        char *cp; // a char pointer used to parse each line.
         if ((cp = strchr (line, '\n')) != NULL) {
             /* chop \n characters */
             *cp = '\0';
         }
-        if ((cp = strtok (line, "\t ")) != NULL) {
+        if (strtok(line, "\t ") != NULL) {
+            // NP: line begins with IP/mask. Skipped to the end of it with this strtok()
+
             /* get the username */
-            username = strtok (NULL, "\t ");
+            char *username;
+            if ((username = strtok(NULL, "\t ")) == NULL) {
+                debug("Missing username on line %u of dictionary file\n", lineCount);
+                continue;
+            }
+
             /* look for a netmask */
             if ((cp = strtok (line, "/")) != NULL) {
                 /* store the ip address in a temporary buffer */
@@ -209,7 +217,6 @@
 int
 main (int argc, char *argv[])
 {
-    FILE *FH;
     char *filename = NULL;
     char *program_name = argv[0];
     char *cp;
@@ -241,7 +248,11 @@
         usage(program_name);
         exit(1);
     }
-    FH = fopen(filename, "r");
+    FILE *FH = fopen(filename, "r");
+    if (!FH) {
+        fprintf(stderr, "%s: FATAL: Unable to open file '%s': %s", program_name, filename, xstrerror());
+        exit(1);
+    }
     current_entry = load_dict(FH);
 
     while (fgets(line, HELPER_INPUT_BUFFER, stdin)) {
diff -u -r -N squid-3.3.0.1/helpers/external_acl/LM_group/ext_lm_group_acl.cc squid-3.3.0.2/helpers/external_acl/LM_group/ext_lm_group_acl.cc
--- squid-3.3.0.1/helpers/external_acl/LM_group/ext_lm_group_acl.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/external_acl/LM_group/ext_lm_group_acl.cc	2012-12-02 21:30:11.000000000 +1300
@@ -69,7 +69,8 @@
 
 #include "squid.h"
 #include "helpers/defines.h"
-#include "include/util.h"
+#include "rfc1738.h"
+#include "util.h"
 
 #if _SQUID_CYGWIN_
 #include <wchar.h>
diff -u -r -N squid-3.3.0.1/helpers/external_acl/SQL_session/ext_sql_session_acl.8 squid-3.3.0.2/helpers/external_acl/SQL_session/ext_sql_session_acl.8
--- squid-3.3.0.1/helpers/external_acl/SQL_session/ext_sql_session_acl.8	2012-10-21 01:02:18.000000000 +1300
+++ squid-3.3.0.2/helpers/external_acl/SQL_session/ext_sql_session_acl.8	2012-12-02 21:48:04.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_SQL_SESSION_ACL 1"
-.TH EXT_SQL_SESSION_ACL 1 "2012-10-20" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH EXT_SQL_SESSION_ACL 1 "2012-12-02" "perl v5.10.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-3.3.0.1/helpers/external_acl/time_quota/ext_time_quota_acl.cc squid-3.3.0.2/helpers/external_acl/time_quota/ext_time_quota_acl.cc
--- squid-3.3.0.1/helpers/external_acl/time_quota/ext_time_quota_acl.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/external_acl/time_quota/ext_time_quota_acl.cc	2012-12-02 21:30:11.000000000 +1300
@@ -264,7 +264,9 @@
     FH = fopen(filename, "r");
     if ( FH ) {
         /* the pointer to the first entry in the linked list */
-        while ((cp = fgets (line, sizeof(line), FH)) != NULL) {
+        unsigned int lineCount = 0;
+        while (fgets(line, sizeof(line), FH)) {
+            ++lineCount;
             if (line[0] == '#') {
                 continue;
             }
@@ -272,13 +274,18 @@
                 /* chop \n characters */
                 *cp = '\0';
             }
-            log_debug("read config line \"%s\".\n", line);
-            if ((cp = strtok (line, "\t ")) != NULL) {
-                username = cp;
+            log_debug("read config line %u: \"%s\".\n", lineCount, line);
+            if ((username = strtok(line, "\t ")) != NULL) {
 
                 /* get the time budget */
-                budget = strtok (NULL, "/");
-                period = strtok (NULL, "/");
+                if ((budget = strtok(NULL, "/")) == NULL) {
+                    fprintf(stderr, "ERROR: missing 'budget' field on line %u of '%s'.\n", lineCount, filename);
+                    continue;
+                }
+                if ((period = strtok(NULL, "/")) == NULL) {
+                    fprintf(stderr, "ERROR: missing 'period' field on line %u of '%s'.\n", lineCount, filename);
+                    continue;
+                }
 
                 parseTime(budget, &budgetSecs, &start);
                 parseTime(period, &periodSecs, &start);
@@ -437,10 +444,12 @@
 
     log_info("Waiting for requests...\n");
     while (fgets(request, HELPER_INPUT_BUFFER, stdin)) {
-        // we expect the following line syntax: "%LOGIN
-        const char *user_key = NULL;
-        user_key = strtok(request, " \n");
-
+        // we expect the following line syntax: %LOGIN
+        const char *user_key = strtok(request, " \n");
+        if (!user_key) {
+            SEND_ERR("User name missing");
+            continue;
+        }
         processActivity(user_key);
     }
     log_info("Ending %s\n", __FILE__);
diff -u -r -N squid-3.3.0.1/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.3.0.2/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-3.3.0.1/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8	2012-10-21 01:02:18.000000000 +1300
+++ squid-3.3.0.2/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8	2012-12-02 21:48:04.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_WBINFO_GROUP_ACL.PL.IN 1"
-.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2012-10-20" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2012-12-02" "perl v5.10.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-3.3.0.1/helpers/log_daemon/DB/log_db_daemon.8 squid-3.3.0.2/helpers/log_daemon/DB/log_db_daemon.8
--- squid-3.3.0.1/helpers/log_daemon/DB/log_db_daemon.8	2012-10-21 01:02:19.000000000 +1300
+++ squid-3.3.0.2/helpers/log_daemon/DB/log_db_daemon.8	2012-12-02 21:48:05.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "LOG_DB_DAEMON 1"
-.TH LOG_DB_DAEMON 1 "2012-10-20" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH LOG_DB_DAEMON 1 "2012-12-02" "perl v5.10.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-3.3.0.1/helpers/log_daemon/file/log_file_daemon.cc squid-3.3.0.2/helpers/log_daemon/file/log_file_daemon.cc
--- squid-3.3.0.1/helpers/log_daemon/file/log_file_daemon.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/log_daemon/file/log_file_daemon.cc	2012-12-02 21:30:11.000000000 +1300
@@ -57,16 +57,24 @@
         snprintf(from, MAXPATHLEN, "%s.%d", path, i - 1);
         snprintf(to, MAXPATHLEN, "%s.%d", path, i);
 #if _SQUID_OS2_ || _SQUID_WINDOWS_
-        remove(to);
+        if (remove(to) < 0) {
+            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerror());
+        }
 #endif
-        rename(from, to);
+        if (rename(path, to) < 0 && errno != ENOENT) {
+            fprintf(stderr, "WARNING: rename '%s' to '%s' failure: %s\n", path, to, xstrerror());
+        }
     }
     if (rotate_count > 0) {
         snprintf(to, MAXPATHLEN, "%s.%d", path, 0);
 #if _SQUID_OS2_ || _SQUID_WINDOWS_
-        remove(to);
+        if (remove(to) < 0) {
+            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerror());
+        }
 #endif
-        rename(path, to);
+        if (rename(path, to) < 0 && errno != ENOENT) {
+            fprintf(stderr, "WARNING: rename %s to %s failure: %s\n", path, to, xstrerror());
+        }
     }
 }
 
@@ -119,7 +127,7 @@
                      * out of device space - recover by rotating and hoping that rotation count drops a big one.
                      */
                     if (err == EFBIG || err == ENOSPC) {
-                        fprintf(stderr, "WARNING: %s writing %s. Attempting to recover via a log rotation.\n",strerror(err),argv[1]);
+                        fprintf(stderr, "WARNING: %s writing %s. Attempting to recover via a log rotation.\n",xstrerr(err),argv[1]);
                         fclose(fp);
                         rotate(argv[1], rotate_count);
                         fp = fopen(argv[1], "a");
diff -u -r -N squid-3.3.0.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc squid-3.3.0.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc
--- squid-3.3.0.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -119,7 +119,7 @@
     struct addrinfo *hres = NULL, *hres_list;
     int rc, count;
 
-    rc = gethostname(hostname, sysconf(_SC_HOST_NAME_MAX));
+    rc = gethostname(hostname, sizeof(hostname)-1);
     if (rc) {
         fprintf(stderr, "%s| %s: ERROR: resolving hostname '%s' failed\n",
                 LogTime(), PROGRAM, hostname);
@@ -148,7 +148,7 @@
         return NULL;
     }
     freeaddrinfo(hres);
-    hostname[sysconf(_SC_HOST_NAME_MAX) - 1] = '\0';
+    hostname[sizeof(hostname)-1] = '\0';
     return (xstrdup(hostname));
 }
 
diff -u -r -N squid-3.3.0.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc squid-3.3.0.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc
--- squid-3.3.0.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc	2012-12-02 21:30:11.000000000 +1300
@@ -213,14 +213,13 @@
 int
 main(int argc, char *argv[])
 {
-
     const char *Token;
     int count;
 
     if (argc < 2) {
         fprintf(stderr, "%s| %s: Error: No proxy server name given\n",
                 LogTime(), PROGRAM);
-        exit(99);
+        return 99;
     }
     if (argc == 3) {
         count = atoi(argv[2]);
@@ -235,7 +234,7 @@
         fprintf(stdout, "Token: %s\n", Token ? Token : "NULL");
     }
 
-    exit(0);
+    return 0;
 }
 
 #else
@@ -243,7 +242,7 @@
 int
 main(int argc, char *argv[])
 {
-    exit(-1);
+    return -1;
 }
 
 #endif /* HAVE_GSSAPI */
diff -u -r -N squid-3.3.0.1/helpers/ntlm_auth/fake/ntlm_fake_auth.cc squid-3.3.0.2/helpers/ntlm_auth/fake/ntlm_fake_auth.cc
--- squid-3.3.0.1/helpers/ntlm_auth/fake/ntlm_fake_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/ntlm_auth/fake/ntlm_fake_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -84,14 +84,14 @@
 #endif
 
 /* A couple of harmless helper macros */
-#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
+#define SEND(X) {debug("sending '%s' to squid\n",X); printf(X "\n");}
 #ifdef __GNUC__
-#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
-#define SEND4(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
+#define SEND2(X,Y...) {debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);}
+#define SEND4(X,Y...) {debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);}
 #else
 /* no gcc, no debugging. varargs macros are a gcc extension */
-#define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
-#define SEND4(X,Y,Z,W) debug("sending '" X "' to squid\n",Y,Z,W); printf(X "\n",Y,Z,W);
+#define SEND2(X,Y) {debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);}
+#define SEND4(X,Y,Z,W) {debug("sending '" X "' to squid\n",Y,Z,W); printf(X "\n",Y,Z,W);}
 #endif
 
 const char *authenticate_ntlm_domain = "WORKGROUP";
diff -u -r -N squid-3.3.0.1/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc squid-3.3.0.2/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc
--- squid-3.3.0.1/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc	2012-12-02 21:30:11.000000000 +1300
@@ -183,8 +183,11 @@
 {
     /* trying to circumvent some strange problem wih pointers in SMBLib */
     /* Ugly as hell, but the lib is going to be dropped... */
-    strcpy(my_domain,domain);
-    strcpy(my_domain_controller,domain_controller);
+    strncpy(my_domain, domain, sizeof(my_domain)-1);
+    my_domain[sizeof(my_domain)-1] = '\0';
+    strncpy(my_domain_controller, domain_controller, sizeof(my_domain_controller)-1);
+    my_domain_controller[sizeof(my_domain_controller)-1] = '\0';
+
     if (init_challenge(my_domain, my_domain_controller) > 0) {
         return NULL;
     }
diff -u -r -N squid-3.3.0.1/include/MemPoolChunked.h squid-3.3.0.2/include/MemPoolChunked.h
--- squid-3.3.0.1/include/MemPoolChunked.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/include/MemPoolChunked.h	2012-12-02 21:30:11.000000000 +1300
@@ -56,7 +56,6 @@
 
     size_t chunk_size;
     int chunk_capacity;
-    int memPID;
     int chunkCount;
     void *freeCache;
     MemChunk *nextFreeChunk;
diff -u -r -N squid-3.3.0.1/include/version.h squid-3.3.0.2/include/version.h
--- squid-3.3.0.1/include/version.h	2012-10-21 00:33:47.000000000 +1300
+++ squid-3.3.0.2/include/version.h	2012-12-02 21:31:05.000000000 +1300
@@ -7,7 +7,7 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1350732744
+#define SQUID_RELEASE_TIME 1354437010
 #endif
 
 #ifndef APP_SHORTNAME
diff -u -r -N squid-3.3.0.1/lib/rfcnb/rfcnb-util.c squid-3.3.0.2/lib/rfcnb/rfcnb-util.c
--- squid-3.3.0.1/lib/rfcnb/rfcnb-util.c	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/lib/rfcnb/rfcnb-util.c	2012-12-02 21:30:11.000000000 +1300
@@ -425,6 +425,7 @@
     char resp[16];
     int len;
     struct RFCNB_Pkt *pkt, res_pkt;
+    int result = 0;
 
     /* We build and send the session request, then read the response */
 
@@ -450,7 +451,7 @@
 #endif
 
     if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) {
-
+        RFCNB_Free_Pkt(pkt);
         return (RFCNBE_Bad);    /* Should be able to write that lot ... */
 
     }
@@ -463,7 +464,7 @@
     res_pkt.next = NULL;
 
     if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) {
-
+        RFCNB_Free_Pkt(pkt);
         return (RFCNBE_Bad);
 
     }
@@ -497,12 +498,12 @@
             break;
         }
 
-        return (RFCNBE_Bad);
+        result = (RFCNBE_Bad);
         break;
 
     case RFCNB_SESSION_ACK:     /* Got what we wanted ...      */
 
-        return (0);
+        result = (0);
         break;
 
     case RFCNB_SESSION_RETARGET:        /* Go elsewhere                */
@@ -512,13 +513,16 @@
         memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr));
         *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
 
-        return (0);
+        result = (0);
         break;
 
     default:                    /* A protocol error */
 
         RFCNB_errno = RFCNBE_ProtErr;
-        return (RFCNBE_Bad);
+        result = (RFCNBE_Bad);
         break;
     }
+
+    RFCNB_Free_Pkt(pkt);
+    return result;
 }
diff -u -r -N squid-3.3.0.1/RELEASENOTES.html squid-3.3.0.2/RELEASENOTES.html
--- squid-3.3.0.1/RELEASENOTES.html	2012-10-21 01:02:25.000000000 +1300
+++ squid-3.3.0.2/RELEASENOTES.html	2012-12-02 21:48:12.000000000 +1300
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.66">
- <TITLE>Squid 3.3.0.0 release notes</TITLE>
+ <TITLE>Squid 3.3.0.2 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.3.0.0 release notes</H1>
+<H1>Squid 3.3.0.2 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -24,7 +24,11 @@
 <H2><A NAME="toc2">2.</A> <A HREF="#s2">Major new features since Squid-3.2</A></H2>
 
 <UL>
-<LI><A NAME="toc2.1">2.1</A> <A HREF="#ss2.1"></A>
+<LI><A NAME="toc2.1">2.1</A> <A HREF="#ss2.1">SQL Database logging helper</A>
+<LI><A NAME="toc2.2">2.2</A> <A HREF="#ss2.2">Time-Quota session helper</A>
+<LI><A NAME="toc2.3">2.3</A> <A HREF="#ss2.3">SSL-Bump Server First</A>
+<LI><A NAME="toc2.4">2.4</A> <A HREF="#ss2.4">Server Certificate Mimic</A>
+<LI><A NAME="toc2.5">2.5</A> <A HREF="#ss2.5">Custom HTTP request headers</A>
 </UL>
 <P>
 <H2><A NAME="toc3">3.</A> <A HREF="#s3">Changes to squid.conf since Squid-3.2</A></H2>
@@ -43,25 +47,16 @@
 <LI><A NAME="toc4.3">4.3</A> <A HREF="#ss4.3">Removed options</A>
 </UL>
 <P>
-<H2><A NAME="toc5">5.</A> <A HREF="#s5">Options Removed since Squid-2</A></H2>
+<H2><A NAME="toc5">5.</A> <A HREF="#s5">Regressions since Squid-2.7</A></H2>
 
 <UL>
-<LI><A NAME="toc5.1">5.1</A> <A HREF="#ss5.1">Removed squid.conf options since Squid-2.7</A>
-<LI><A NAME="toc5.2">5.2</A> <A HREF="#ss5.2">Removed squid.conf options since Squid-2.6</A>
-<LI><A NAME="toc5.3">5.3</A> <A HREF="#ss5.3">Removed ./configure options since Squid-2.7</A>
-</UL>
-<P>
-<H2><A NAME="toc6">6.</A> <A HREF="#s6">Regressions since Squid-2.7</A></H2>
-
-<UL>
-<LI><A NAME="toc6.1">6.1</A> <A HREF="#ss6.1">Missing squid.conf options available in Squid-2.7</A>
-<LI><A NAME="toc6.2">6.2</A> <A HREF="#ss6.2">Missing ./configure options available in Squid-2.7</A>
+<LI><A NAME="toc5.1">5.1</A> <A HREF="#ss5.1">Missing squid.conf options available in Squid-2.7</A>
 </UL>
 
 <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.3.0.0 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.3.0.2 for testing.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.3/">http://www.squid-cache.org/Versions/v3/3.3/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
@@ -87,15 +82,142 @@
 
 <P>The most important of these new features are:
 <UL>
-<LI></LI>
+<LI>SQL Database logging helper</LI>
+<LI>Time-Quota session helper</LI>
+<LI>SSL-Bump Server First</LI>
+<LI>Server Certificate Mimic</LI>
+<LI>Custom HTTP request headers</LI>
 </UL>
 </P>
 <P>Most user-facing changes are reflected in squid.conf (see below).</P>
 
-<H2><A NAME="ss2.1">2.1</A> <A HREF="#toc2.1"></A>
+<H2><A NAME="ss2.1">2.1</A> <A HREF="#toc2.1">SQL Database logging helper</A>
+</H2>
+
+<P><EM>log_db_daemon</EM> - Database logging daemon for Squid</P>
+
+<P>This program writes Squid access.log entries to an SQL database.
+Written in Perl it can utilize any database supported by the Perl
+database abstraction layer.</P>
+
+<P>NOTE: Presently it only accepts the Squid native log format.</P>
+
+
+<H2><A NAME="ss2.2">2.2</A> <A HREF="#toc2.2">Time-Quota session helper</A>
+</H2>
+
+<P><EM>ext_time_quota_acl</EM> - Time quota external ACL helper.</P>
+
+<P>Allows an administrator to define time budgets (quota) for the
+users of Squid to limit the time using Squid.</P>
+
+<P>This is useful for corporate lunch time allocations, wifi portal
+pay-per-minute installations or for parental control of children.</P>
+
+<P>The administrator can define a time budget (e.g. 1 hour per day)
+which is enforced through this helper using session estimations
+of their browsing time. A 'pause' threshold is given in seconds
+and defines the period between two requests to be treated as part
+of the same session. Pauses shorter than this value will be
+counted against the quota, longer ones ignored.</P>
+
+
+<H2><A NAME="ss2.3">2.3</A> <A HREF="#toc2.3">SSL-Bump Server First</A>
+</H2>
+
+<P>Details at 
+<A HREF="http://wiki.squid-cache.org/Features/BumpSslServerFirst">http://wiki.squid-cache.org/Features/BumpSslServerFirst</A>.</P>
+
+<P>When an intercepted connection is received, Squid first connects
+to the server using SSL and receives the server certificate.
+Squid then uses the host name inside the true server certificate
+to generate a fake one and impersonates the server while still
+using the already established secure connection to the server.</P>
+
+<P>Bumping server first is essentially required for handling
+intercepted HTTPS connections but the same scheme should be used
+for most HTTP CONNECT requests because it offers a few advantages
+compared to the old bump-client-first approach:</P>
+<P>
+<UL>
+<LI>When Squid knows valid server certificate details, it can
+generate its fake server certificate with those details.
+With the bump-client-first scheme, all those details are lost.
+In general, browsers do not care about those details but there
+may be HTTP clients (or even human users) that require or could
+benefit from knowing them.
+</LI>
+<LI>When a server sends a bad certificate, Squid may be able to
+replicate that brokenness in its own fake certificate, giving
+the HTTP client control whether to ignore the problem or
+terminate the transaction. With bump-client-furst, it is
+difficult to support similar dynamic, user-directed opt out; 
+Squid itself has to decide what to do when the server
+certificate cannot be validated.
+</LI>
+<LI>When a server asks for a client certificate, Squid may be
+able to ask the client and then forward the client certificate
+to the server. Such client certificate handling may not be
+possible with the bump-client-first scheme because it would
+have to be done after the SSL handshake.
+</LI>
+<LI>Some clients (e.g., Rekonq browser v0.7.x) do not send host
+names in CONNECT requests. Such clients require bump-server-first
+even in forward proxying mode. Unfortunately, there are other
+problems with fully supporting such clients (i.e., Squid does
+not know whether the IP address in the CONNECT request is what
+the user have typed into the address bar) so not all features
+will work well for them until more specialized detection code
+is added.</LI>
+</UL>
+</P>
+
+<H2><A NAME="ss2.4">2.4</A> <A HREF="#toc2.4">Server Certificate Mimic</A>
 </H2>
 
+<P>Details at 
+<A HREF="http://wiki.squid-cache.org/Features/MimicSslServerCert">http://wiki.squid-cache.org/Features/MimicSslServerCert</A>.</P>
 
+<P>One of the SslBump features serious drawbacks is the loss of
+information embedded in SSL server certificate.
+This certificate mimic feature passes original SSL server
+certificate information to the user. Allowing the user to
+make an informed decision on whether to trust the server
+certificate.</P>
+
+
+<H2><A NAME="ss2.5">2.5</A> <A HREF="#toc2.5">Custom HTTP request headers</A>
+</H2>
+
+<P>The <EM>request_header_add</EM> option is added to insert
+HTTP header fields to outgoing HTTP requests (i.e.,
+request headers sent by Squid to the next HTTP hop such as a
+cache peer or an origin server). The option has no effect on
+cache hit traffic or requests serviced by Squid and ICAP.</P>
+
+<P>WARNING: If a standard HTTP header name is used, Squid does not check whether
+the new header conflicts with any existing headers or violates
+HTTP rules. If the request to be modified already contains a
+field with the same name, the old field is preserved but the
+header field values are not merged.</P>
+
+<P>Field-value set can be either a token or a quoted string. If quoted
+string format is used, then the surrounding quotes are removed
+while escape sequences and %macros are processed.</P>
+
+<P>In theory, all of the <EM>logformat</EM> codes can be used as %macros.
+However, unlike logging (which happens at the very end of
+transaction lifetime), the transaction may not yet have enough
+information to expand a macro when the new header value is needed.
+And some information may already be available to Squid but not yet
+committed where the macro expansion code can access it (please report
+such instances!). The macro will be expanded into a single dash
+('-') in such cases. Not all macros have been tested.</P>
+
+<P>One or more Squid ACLs may be specified to restrict header
+injection to matching requests. As always in squid.conf, all
+ACLs in an option ACL list must be satisfied for the insertion
+to happen. The <EM>request_header_add</EM> option supports fast ACLs only.</P>
 
 
 <H2><A NAME="s3">3.</A> <A HREF="#toc3">Changes to squid.conf since Squid-3.2</A></H2>
@@ -119,6 +241,15 @@
 
 <P>
 <DL>
+<DT><B>request_header_add</B><DD>
+<P>New directive to add custom headers on HTTP traffic sent to upstream servers.</P>
+
+<DT><B>sslproxy_cert_sign</B><DD>
+<P>New option to determine how the client certificate sent to upstream servers is signed.</P>
+
+<DT><B>sslproxy_cert_adapt</B><DD>
+<P>New option to adapt certain properties of outgoing SSL certificates generated for use when bumping SSL to an upstream server.</P>
+
 
 </DL>
 </P>
@@ -128,16 +259,40 @@
 
 <P>
 <DL>
+<DT><B>acl</B><DD>
+<P><EM>myport</EM> and <EM>myip</EM>ACL types replaced with <EM>localport</EM> and <EM>localip</EM> respecitively.
+To reflect that it matches the TCP connection details and not the squid.conf port.
+This matters when dealing with interecepted traffic, where the Squid receiving port differs from the TCP connection IP:port.
+Always use <EM>myportname</EM> type to match the squid.conf port details.</P>
+<P>New default built-in ACLs for testing SSL certificate properties.</P>
+<P><EM>ssl::certHasExpired</EM>,
+<EM>ssl::certNotYetValid</EM>,
+<EM>ssl::certDomainMismatch</EM>,
+<EM>ssl::certUntrusted</EM>,
+<EM>ssl::certSelfSigned</EM>.</P>
+
+<DT><B>logformat</B><DD>
+<P>New token <EM>%ssl::bump_mode</EM> to log the SSL-bump mode type performed on a request.
+Logs values of: <EM>-</EM>, <EM>none</EM>, <EM>client-first</EM>, or <EM>server-first</EM>.</P>
+<P>New token of <EM>%ssl::&gt;cert_subject</EM> to log the Subject field of a SSL certficate received from the client.</P>
+<P>New token of <EM>%ssl::&gt;cert_issuer</EM> to log the Issuer field of a SSL certficate received from the client.</P>
+
+<DT><B>ssl_bump</B><DD>
+<P>New action types <EM>none</EM>, <EM>client-first</EM>, <EM>server-first</EM>. The default is <EM>none</EM>.</P>
+<P>Use of <EM>allow</EM>/<EM>deny</EM> is now deprecated and they should be removed as soon as possible.
+To retain the exact same behaviour between 3.3 and older releases replace <EM>deny</EM> with <EM>none</EM>,
+and <EM>allow</EM> with <EM>client-first</EM>. However an upgrade to <EM>server-first</EM> is the recommended.</P>
+<P><EM>NOTE</EM>: Mixing of allow/deny with the new action types is prohibited and will cause Squid to exit with a FATAL error.</P>
 
 </DL>
 </P>
 
-
 <H2><A NAME="removedtags"></A> <A NAME="ss3.3">3.3</A> <A HREF="#toc3.3">Removed tags</A>
 </H2>
 
 <P>
 <DL>
+<P><EM>There are no removed squid.conf tags in Squid-3.3.</EM></P>
 
 </DL>
 </P>
@@ -164,6 +319,7 @@
 
 <P>
 <DL>
+<P><EM>There are no new ./configure options in Squid-3.3.</EM></P>
 
 </DL>
 </P>
@@ -173,6 +329,7 @@
 
 <P>
 <DL>
+<P><EM>There are no changed ./configure options in Squid-3.3.</EM></P>
 
 </DL>
 </P>
@@ -181,163 +338,24 @@
 
 <P>
 <DL>
+<DT><B>--enable-ntlm-fail-open</B><DD>
+<P>This has not been supported by Squid for several versions.</P>
 
 </DL>
 </P>
 
 
-<H2><A NAME="s5">5.</A> <A HREF="#toc5">Options Removed since Squid-2</A></H2>
-
-<P>Some squid.conf and ./configure options which were available in Squid-2.6 and Squid-2.7 are made obsolete in Squid-3.3.</P>
-
-<H2><A NAME="ss5.1">5.1</A> <A HREF="#toc5.1">Removed squid.conf options since Squid-2.7</A>
-</H2>
-
-<P>
-<DL>
-<DT><B>auth_param</B><DD>
-<P><EM>blankpassword</EM> option for basic scheme removed.</P>
-
-<DT><B>cache_peer</B><DD>
-<P><EM>http11</EM> Obsolete.</P>
-
-<DT><B>external_acl_type</B><DD>
-<P>Format tag <EM>%{Header}</EM> replaced by <EM>%>{Header}</EM></P>
-<P>Format tag <EM>%{Header:member}</EM> replaced by <EM>%>{Header:member}</EM></P>
-
-<DT><B>header_access</B><DD>
-<P>Replaced by <EM>request_header_access</EM> and <EM>reply_header_access</EM></P>
-
-<DT><B>http_port</B><DD>
-<P><EM>no-connection-auth</EM> replaced by <EM>connection-auth=[on|off]</EM>. Default is ON.</P>
-<P><EM>transparent</EM> option replaced by <EM>intercept</EM></P>
-<P><EM>http11</EM> obsolete.</P>
-
-<DT><B>http_access2</B><DD>
-<P>Replaced by <EM>adapted_http_access</EM></P>
-
-<DT><B>httpd_accel_no_pmtu_disc</B><DD>
-<P>Replaced by <EM>http_port disable-pmtu-discovery=</EM> option</P>
-
-<DT><B>incoming_rate</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>redirector_bypass</B><DD>
-<P>Replaced by <EM>url_rewrite_bypass</EM></P>
-
-<DT><B>server_http11</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>upgrade_http0.9</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>zph_local</B><DD>
-<P>Replaced by <EM>qos_flows local-hit=</EM></P>
-
-<DT><B>zph_mode</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>zph_option</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>zph_parent</B><DD>
-<P>Replaced by <EM>qos_flows parent-hit=</EM></P>
-
-<DT><B>zph_sibling</B><DD>
-<P>Replaced by <EM>qos_flows sibling-hit=</EM></P>
-
-</DL>
-</P>
-
-<H2><A NAME="ss5.2">5.2</A> <A HREF="#toc5.2">Removed squid.conf options since Squid-2.6</A>
-</H2>
-
-<P>
-<DL>
-<DT><B>cache_dir</B><DD>
-<P><EM>read-only</EM> option replaced by <EM>no-store</EM>.</P>
-
-</DL>
-</P>
-
-<H2><A NAME="ss5.3">5.3</A> <A HREF="#toc5.3">Removed ./configure options since Squid-2.7</A>
-</H2>
-
-<P>
-<DL>
-<DT><B>--enable-coss-aio-ops</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-devpoll</B><DD>
-<P>Replaced by automatic detection.</P>
-
-<DT><B>--enable-dlmalloc=LIB</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-epoll</B><DD>
-<P>Replaced by automatic detection.</P>
-
-<DT><B>--enable-forward-log</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-heap-replacement</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-htcp</B><DD>
-<P>Obsolete. Enabled by default.</P>
-
-<DT><B>--enable-large-cache-files</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-mempool-debug</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-multicast-miss</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--enable-poll</B><DD>
-<P>Replaced by automatic detection.</P>
-
-<DT><B>--enable-select</B><DD>
-<P>Replaced by automatic detection.</P>
-
-<DT><B>--enable-select-simple</B><DD>
-<P>Replaced by automatic detection.</P>
-
-<DT><B>--enable-snmp</B><DD>
-<P>Obsolete. Enabled by default.</P>
-
-<DT><B>--enable-truncate</B><DD>
-<P>Obsolete.</P>
-
-<DT><B>--disable-kqueue</B><DD>
-<P>Obsolete. Disabled by default.</P>
-
-</DL>
-</P>
-
-
-<H2><A NAME="s6">6.</A> <A HREF="#toc6">Regressions since Squid-2.7</A></H2>
+<H2><A NAME="s5">5.</A> <A HREF="#toc5">Regressions since Squid-2.7</A></H2>
 
 <P>Some squid.conf and ./configure options which were available in Squid-2.7 are not yet available in Squid-3.3</P>
 
 <P>If you need something to do then porting one of these from Squid-2 to Squid-3 is most welcome.</P>
 
-<H2><A NAME="ss6.1">6.1</A> <A HREF="#toc6.1">Missing squid.conf options available in Squid-2.7</A>
+<H2><A NAME="ss5.1">5.1</A> <A HREF="#toc5.1">Missing squid.conf options available in Squid-2.7</A>
 </H2>
 
 <P>
 <DL>
-<DT><B>acl</B><DD>
-<P><EM>urllogin</EM> option not yet ported from 2.6</P>
-<P><EM>urlgroup</EM> option not yet ported from 2.6</P>
-
-<DT><B>authenticate_ip_shortcircuit_access</B><DD>
-<P>Not yet ported from 2.7</P>
-
-<DT><B>authenticate_ip_shortcircuit_ttl</B><DD>
-<P>Not yet ported from 2.7</P>
-
 <DT><B>broken_vary_encoding</B><DD>
 <P>Not yet ported from 2.6</P>
 
@@ -373,7 +391,6 @@
 
 <DT><B>http_port</B><DD>
 <P><EM>act-as-origin</EM> not yet ported from 2.7</P>
-<P><EM>urlgroup=</EM> not yet ported from 2.6</P>
 
 <DT><B>ignore_ims_on_miss</B><DD>
 <P>Not yet ported from 2.7</P>
@@ -390,9 +407,6 @@
 <DT><B>location_rewrite_program</B><DD>
 <P>Not yet ported from 2.6</P>
 
-<DT><B>logformat</B><DD>
-<P><EM>%oa</EM> tag not yet ported from 2.7</P>
-
 <DT><B>refresh_pattern</B><DD>
 <P><EM>stale-while-revalidate=</EM> not yet ported from 2.7</P>
 <P><EM>ignore-stale-while-revalidate=</EM> not yet ported from 2.7</P>
@@ -416,19 +430,6 @@
 <DT><B>update_headers</B><DD>
 <P>Not yet ported from 2.7</P>
 
-<DT><B>zero_buffers</B><DD>
-<P>Not yet ported from 2.7</P>
-
-</DL>
-</P>
-
-<H2><A NAME="ss6.2">6.2</A> <A HREF="#toc6.2">Missing ./configure options available in Squid-2.7</A>
-</H2>
-
-<P>
-<DL>
-<DT><B>--without-system-md5</B><DD>
-
 </DL>
 </P>
 
diff -u -r -N squid-3.3.0.1/src/AccessLogEntry.cc squid-3.3.0.2/src/AccessLogEntry.cc
--- squid-3.3.0.1/src/AccessLogEntry.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/AccessLogEntry.cc	2012-12-02 21:30:11.000000000 +1300
@@ -22,7 +22,7 @@
         if (tcpClient != NULL)
             tcpClient->remote.NtoA(buf, bufsz);
         else if (cache.caddr.IsNoAddr()) // e.g., ICAP OPTIONS lack client
-            strncpy(buf, "-", 1);
+            strncpy(buf, "-", bufsz);
         else
             cache.caddr.NtoA(buf, bufsz);
 }
diff -u -r -N squid-3.3.0.1/src/acl/Acl.cc squid-3.3.0.2/src/acl/Acl.cc
--- squid-3.3.0.1/src/acl/Acl.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Acl.cc	2012-12-02 21:30:11.000000000 +1300
@@ -80,7 +80,12 @@
     return result;
 }
 
-ACL::ACL () :cfgline(NULL) {}
+ACL::ACL() :
+        cfgline(NULL),
+        next(NULL)
+{
+    *name = 0;
+}
 
 bool ACL::valid () const
 {
diff -u -r -N squid-3.3.0.1/src/acl/Asn.cc squid-3.3.0.2/src/acl/Asn.cc
--- squid-3.3.0.1/src/acl/Asn.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Asn.cc	2012-12-02 21:30:11.000000000 +1300
@@ -509,8 +509,6 @@
         data = data->next;
         delete prev;
     }
-
-    delete data;
 }
 
 static int
diff -u -r -N squid-3.3.0.1/src/acl/Checklist.cc squid-3.3.0.2/src/acl/Checklist.cc
--- squid-3.3.0.1/src/acl/Checklist.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Checklist.cc	2012-12-02 21:30:11.000000000 +1300
@@ -320,7 +320,8 @@
         async_(false),
         finished_(false),
         allow_(ACCESS_DENIED),
-        state_(NullState::Instance())
+        state_(NullState::Instance()),
+        checking_(false)
 {
 }
 
diff -u -r -N squid-3.3.0.1/src/acl/DestinationIp.cc squid-3.3.0.2/src/acl/DestinationIp.cc
--- squid-3.3.0.1/src/acl/DestinationIp.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/DestinationIp.cc	2012-12-02 21:30:11.000000000 +1300
@@ -54,8 +54,7 @@
     // Bypass of browser same-origin access control in intercepted communication
     // To resolve this we will force DIRECT and only to the original client destination.
     // In which case, we also need this ACL to accurately match the destination
-    if (Config.onoff.client_dst_passthru && checklist->request &&
-            (checklist->request->flags.intercepted || checklist->request->flags.spoofClientIp)) {
+    if (Config.onoff.client_dst_passthru && (checklist->request->flags.intercepted || checklist->request->flags.spoofClientIp)) {
         assert(checklist->conn() && checklist->conn()->clientConnection != NULL);
         return ACLIP::match(checklist->conn()->clientConnection->local);
     }
diff -u -r -N squid-3.3.0.1/src/acl/HttpHeaderData.cc squid-3.3.0.2/src/acl/HttpHeaderData.cc
--- squid-3.3.0.1/src/acl/HttpHeaderData.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/HttpHeaderData.cc	2012-12-02 21:30:11.000000000 +1300
@@ -65,9 +65,23 @@
 
     debugs(28, 3, "aclHeaderData::match: checking '" << hdrName << "'");
 
-    String value = hdrId != HDR_BAD_HDR ? hdr->getStrOrList(hdrId) : hdr->getByName(hdrName.termedBuf());
+    String value;
+    if (hdrId != HDR_BAD_HDR) {
+        if (!hdr->has(hdrId))
+            return false;
+        value = hdr->getStrOrList(hdrId);
+    } else {
+        if (!hdr->getByNameIfPresent(hdrName.termedBuf(), value))
+            return false;
+    }
 
-    return regex_rule->match(value.termedBuf());
+    // By now, we know the header is present, but:
+    // HttpHeader::get*() return an undefined String for empty header values;
+    // String::termedBuf() returns NULL for undefined Strings; and
+    // ACLRegexData::match() always fails on NULL strings.
+    // This makes it possible to detect an empty header value using regex:
+    const char *cvalue = value.defined() ? value.termedBuf() : "";
+    return regex_rule->match(cvalue);
 }
 
 wordlist *
diff -u -r -N squid-3.3.0.1/src/acl/Ip.cc squid-3.3.0.2/src/acl/Ip.cc
--- squid-3.3.0.1/src/acl/Ip.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Ip.cc	2012-12-02 21:30:11.000000000 +1300
@@ -409,15 +409,6 @@
 
         memset(&hints, 0, sizeof(struct addrinfo));
 
-        if ( iptype != AF_UNSPEC ) {
-            hints.ai_flags |= AI_NUMERICHOST;
-        }
-
-#if 0
-        if (Ip::EnableIpv6&IPV6_SPECIAL_V4MAPPING)
-            hints.ai_flags |= AI_V4MAPPED | AI_ALL;
-#endif
-
         int errcode = getaddrinfo(addr1,NULL,&hints,&hp);
         if (hp == NULL) {
             debugs(28, DBG_CRITICAL, "aclIpParseIpData: Bad host/IP: '" << addr1 <<
diff -u -r -N squid-3.3.0.1/src/acl/Makefile.am squid-3.3.0.2/src/acl/Makefile.am
--- squid-3.3.0.1/src/acl/Makefile.am	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Makefile.am	2012-12-02 21:30:11.000000000 +1300
@@ -98,6 +98,8 @@
 	Tag.h \
 	Url.cc \
 	Url.h \
+	UrlLogin.cc \
+	UrlLogin.h \
 	UrlPath.cc \
 	UrlPath.h \
 	UrlPort.cc \
diff -u -r -N squid-3.3.0.1/src/acl/Makefile.in squid-3.3.0.2/src/acl/Makefile.in
--- squid-3.3.0.1/src/acl/Makefile.in	2012-10-21 00:33:16.000000000 +1300
+++ squid-3.3.0.2/src/acl/Makefile.in	2012-12-02 21:30:44.000000000 +1300
@@ -76,12 +76,13 @@
 	Referer.cc Referer.h ReplyHeaderStrategy.h ReplyMimeType.cc \
 	ReplyMimeType.h RequestHeaderStrategy.h RequestMimeType.cc \
 	RequestMimeType.h SourceAsn.h SourceDomain.cc SourceDomain.h \
-	SourceIp.cc SourceIp.h Tag.cc Tag.h Url.cc Url.h UrlPath.cc \
-	UrlPath.h UrlPort.cc UrlPort.h UserData.cc UserData.h \
-	AclNameList.h AclDenyInfoList.h Gadgets.cc Gadgets.h \
-	AclSizeLimit.h CertificateData.cc CertificateData.h \
-	Certificate.cc Certificate.h SslError.cc SslError.h \
-	SslErrorData.cc SslErrorData.h Arp.cc Arp.h Eui64.cc Eui64.h
+	SourceIp.cc SourceIp.h Tag.cc Tag.h Url.cc Url.h UrlLogin.cc \
+	UrlLogin.h UrlPath.cc UrlPath.h UrlPort.cc UrlPort.h \
+	UserData.cc UserData.h AclNameList.h AclDenyInfoList.h \
+	Gadgets.cc Gadgets.h AclSizeLimit.h CertificateData.cc \
+	CertificateData.h Certificate.cc Certificate.h SslError.cc \
+	SslError.h SslErrorData.cc SslErrorData.h Arp.cc Arp.h \
+	Eui64.cc Eui64.h
 am__objects_1 = CertificateData.lo Certificate.lo SslError.lo \
 	SslErrorData.lo
 @ENABLE_SSL_TRUE@am__objects_2 = $(am__objects_1)
@@ -95,8 +96,8 @@
 	MaxConnection.lo Method.lo MethodData.lo MyPortName.lo \
 	PeerName.lo Protocol.lo ProtocolData.lo Random.lo Referer.lo \
 	ReplyMimeType.lo RequestMimeType.lo SourceDomain.lo \
-	SourceIp.lo Tag.lo Url.lo UrlPath.lo UrlPort.lo UserData.lo \
-	Gadgets.lo $(am__objects_2) $(am__objects_4)
+	SourceIp.lo Tag.lo Url.lo UrlLogin.lo UrlPath.lo UrlPort.lo \
+	UserData.lo Gadgets.lo $(am__objects_2) $(am__objects_4)
 libacls_la_OBJECTS = $(am_libacls_la_OBJECTS)
 libapi_la_LIBADD =
 am_libapi_la_OBJECTS = Acl.lo Checklist.lo
@@ -391,10 +392,11 @@
 	Referer.h ReplyHeaderStrategy.h ReplyMimeType.cc \
 	ReplyMimeType.h RequestHeaderStrategy.h RequestMimeType.cc \
 	RequestMimeType.h SourceAsn.h SourceDomain.cc SourceDomain.h \
-	SourceIp.cc SourceIp.h Tag.cc Tag.h Url.cc Url.h UrlPath.cc \
-	UrlPath.h UrlPort.cc UrlPort.h UserData.cc UserData.h \
-	AclNameList.h AclDenyInfoList.h Gadgets.cc Gadgets.h \
-	AclSizeLimit.h $(am__append_2) $(am__append_3)
+	SourceIp.cc SourceIp.h Tag.cc Tag.h Url.cc Url.h UrlLogin.cc \
+	UrlLogin.h UrlPath.cc UrlPath.h UrlPort.cc UrlPort.h \
+	UserData.cc UserData.h AclNameList.h AclDenyInfoList.h \
+	Gadgets.cc Gadgets.h AclSizeLimit.h $(am__append_2) \
+	$(am__append_3)
 EXTRA_libacls_la_SOURCES = $(SSL_ACLS) $(ARP_ACLS)
 SSL_ACLS = \
         CertificateData.cc \
@@ -519,6 +521,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Time.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeData.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Url.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlLogin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlPath.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlPort.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UserData.Plo@am__quote@
diff -u -r -N squid-3.3.0.1/src/acl/MaxConnection.cc squid-3.3.0.2/src/acl/MaxConnection.cc
--- squid-3.3.0.1/src/acl/MaxConnection.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/MaxConnection.cc	2012-12-02 21:30:11.000000000 +1300
@@ -85,8 +85,15 @@
     limit = (atoi (t));
 
     /* suck out file contents */
-
+    // ignore comments
+    bool ignore = false;
     while ((t = strtokFile())) {
+        ignore |= (*t != '#');
+
+        if (ignore)
+            continue;
+
+        debugs(89, DBG_CRITICAL, "WARNING: max_conn only accepts a single limit value.");
         limit = 0;
     }
 }
diff -u -r -N squid-3.3.0.1/src/acl/Random.cc squid-3.3.0.2/src/acl/Random.cc
--- squid-3.3.0.1/src/acl/Random.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Random.cc	2012-12-02 21:30:11.000000000 +1300
@@ -72,6 +72,12 @@
     return data == 0.0;
 }
 
+bool
+ACLRandom::valid() const
+{
+    return !empty();
+}
+
 /*******************/
 /* aclParseRandomList */
 /*******************/
@@ -82,6 +88,9 @@
     char bufa[256], bufb[256];
 
     t = strtokFile();
+    if (!t)
+        return;
+
     debugs(28, 5, "aclParseRandomData: " << t);
 
     // seed random generator ...
@@ -91,23 +100,23 @@
         int a = xatoi(bufa);
         int b = xatoi(bufb);
         if (a == 0 || b == 0) {
-            debugs(28, DBG_CRITICAL, "aclParseRandomData: Bad Pattern: '" << t << "'");
-            self_destruct();
+            debugs(28, DBG_CRITICAL, "ERROR: ACL random with bad pattern: '" << t << "'");
+            return;
         } else
             data = a / (double)(a+b);
     } else if (sscanf(t, "%[0-9]/%[0-9]", bufa, bufb) == 2) {
         int a = xatoi(bufa);
         int b = xatoi(bufb);
         if (a == 0 || b == 0) {
-            debugs(28, DBG_CRITICAL, "aclParseRandomData: Bad Pattern: '" << t << "'");
-            self_destruct();
+            debugs(28, DBG_CRITICAL, "ERROR: ACL random with bad pattern: '" << t << "'");
+            return;
         } else
             data = (double) a / (double) b;
     } else if (sscanf(t, "0.%[0-9]", bufa) == 1) {
         data = atof(t);
     } else {
-        debugs(28, DBG_CRITICAL, "aclParseRandomData: Bad Pattern: '" << t << "'");
-        self_destruct();
+        debugs(28, DBG_CRITICAL, "ERROR: ACL random with bad pattern: '" << t << "'");
+        return;
     }
 
     // save the exact input pattern. so we can display it later.
diff -u -r -N squid-3.3.0.1/src/acl/Random.h squid-3.3.0.2/src/acl/Random.h
--- squid-3.3.0.1/src/acl/Random.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/acl/Random.h	2012-12-02 21:30:11.000000000 +1300
@@ -53,6 +53,7 @@
     virtual int match(ACLChecklist *checklist);
     virtual wordlist *dump() const;
     virtual bool empty () const;
+    virtual bool valid() const;
 
 protected:
     static Prototype RegistryProtoype;
diff -u -r -N squid-3.3.0.1/src/acl/UrlLogin.cc squid-3.3.0.2/src/acl/UrlLogin.cc
--- squid-3.3.0.1/src/acl/UrlLogin.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.3.0.2/src/acl/UrlLogin.cc	2012-12-02 21:30:11.000000000 +1300
@@ -0,0 +1,56 @@
+/*
+ * DEBUG: section 28    Access Control
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+#include "acl/UrlLogin.h"
+#include "acl/Checklist.h"
+#include "acl/RegexData.h"
+#include "HttpRequest.h"
+#include "rfc1738.h"
+
+int
+ACLUrlLoginStrategy::match (ACLData<char const *> * &data, ACLFilledChecklist *checklist)
+{
+    char *esc_buf = xstrdup(checklist->request->login);
+    rfc1738_unescape(esc_buf);
+    int result = data->match(esc_buf);
+    safe_free(esc_buf);
+    return result;
+}
+
+ACLUrlLoginStrategy *
+ACLUrlLoginStrategy::Instance()
+{
+    return &Instance_;
+}
+
+ACLUrlLoginStrategy ACLUrlLoginStrategy::Instance_;
diff -u -r -N squid-3.3.0.1/src/acl/UrlLogin.h squid-3.3.0.2/src/acl/UrlLogin.h
--- squid-3.3.0.1/src/acl/UrlLogin.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.3.0.2/src/acl/UrlLogin.h	2012-12-02 21:30:11.000000000 +1300
@@ -0,0 +1,73 @@
+
+/*
+ * $Id$
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ *
+ * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#ifndef SQUID_ACLURLLOGIN_H
+#define SQUID_ACLURLLOGIN_H
+
+#include "acl/Acl.h"
+#include "acl/Data.h"
+#include "acl/Strategy.h"
+#include "acl/Strategised.h"
+
+class ACLUrlLoginStrategy : public ACLStrategy<char const *>
+{
+
+public:
+    virtual int match (ACLData<char const *> * &, ACLFilledChecklist *);
+    virtual bool requiresRequest() const {return true;}
+
+    static ACLUrlLoginStrategy *Instance();
+    /* Not implemented to prevent copies of the instance. */
+    /* Not private to prevent brain dead g+++ warnings about
+     * private constructors with no friends */
+    ACLUrlLoginStrategy(ACLUrlLoginStrategy const &);
+
+private:
+    static ACLUrlLoginStrategy Instance_;
+    ACLUrlLoginStrategy() {}
+
+    ACLUrlLoginStrategy&operator=(ACLUrlLoginStrategy const &);
+};
+
+class ACLUrlLogin
+{
+
+public:
+    static ACL::Prototype RegistryProtoype;
+    static ACL::Prototype LegacyRegistryProtoype;
+    static ACLStrategised<char const *> RegistryEntry_;
+};
+
+#endif /* SQUID_ACLURLLOGIN_H */
diff -u -r -N squid-3.3.0.1/src/AclRegs.cc squid-3.3.0.2/src/AclRegs.cc
--- squid-3.3.0.1/src/AclRegs.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/AclRegs.cc	2012-12-02 21:30:11.000000000 +1300
@@ -63,6 +63,7 @@
 #include "acl/TimeData.h"
 #include "acl/Time.h"
 #include "acl/Url.h"
+#include "acl/UrlLogin.h"
 #include "acl/UrlPath.h"
 #include "acl/UrlPort.h"
 #include "acl/UserData.h"
@@ -130,6 +131,8 @@
 ACLStrategised<time_t> ACLTime::RegistryEntry_(new ACLTimeData, ACLTimeStrategy::Instance(), "time");
 ACL::Prototype ACLUrl::RegistryProtoype(&ACLUrl::RegistryEntry_, "url_regex");
 ACLStrategised<char const *> ACLUrl::RegistryEntry_(new ACLRegexData, ACLUrlStrategy::Instance(), "url_regex");
+ACL::Prototype ACLUrlLogin::RegistryProtoype(&ACLUrlLogin::RegistryEntry_, "urllogin");
+ACLStrategised<char const *> ACLUrlLogin::RegistryEntry_(new ACLRegexData, ACLUrlLoginStrategy::Instance(), "urllogin");
 ACL::Prototype ACLUrlPath::LegacyRegistryProtoype(&ACLUrlPath::RegistryEntry_, "pattern");
 ACL::Prototype ACLUrlPath::RegistryProtoype(&ACLUrlPath::RegistryEntry_, "urlpath_regex");
 ACLStrategised<char const *> ACLUrlPath::RegistryEntry_(new ACLRegexData, ACLUrlPathStrategy::Instance(), "urlpath_regex");
diff -u -r -N squid-3.3.0.1/src/adaptation/icap/Options.cc squid-3.3.0.2/src/adaptation/icap/Options.cc
--- squid-3.3.0.1/src/adaptation/icap/Options.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/adaptation/icap/Options.cc	2012-12-02 21:30:11.000000000 +1300
@@ -205,8 +205,11 @@
     while (strListGetItem(&buf, ',', &item, &ilen, &pos)) {
         if (ilen == 1 && *item == '*')
             foundStar = true;
-        else
-            add(xstrndup(item, ilen+1));
+        else {
+            const char *tmp = xstrndup(item, ilen+1);
+            add(tmp);
+            xfree(tmp);
+        }
     }
 }
 
diff -u -r -N squid-3.3.0.1/src/adaptation/icap/Xaction.cc squid-3.3.0.2/src/adaptation/icap/Xaction.cc
--- squid-3.3.0.1/src/adaptation/icap/Xaction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/adaptation/icap/Xaction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -45,7 +45,8 @@
         ignoreLastWrite(false),
         connector(NULL), reader(NULL), writer(NULL), closer(NULL),
         alep(new AccessLogEntry),
-        al(*alep)
+        al(*alep),
+        cs(NULL)
 {
     debugs(93,3, typeName << " constructed, this=" << this <<
            " [icapx" << id << ']'); // we should not call virtual status() here
@@ -170,7 +171,7 @@
     // TODO: service bypass status may differ from that of a transaction
     typedef CommCbMemFunT<Adaptation::Icap::Xaction, CommConnectCbParams> ConnectDialer;
     connector = JobCallback(93,3, ConnectDialer, this, Adaptation::Icap::Xaction::noteCommConnected);
-    Comm::ConnOpener *cs = new Comm::ConnOpener(connection, connector, TheConfig.connect_timeout(service().cfg().bypass));
+    cs = new Comm::ConnOpener(connection, connector, TheConfig.connect_timeout(service().cfg().bypass));
     cs->setHost(s.cfg().host.termedBuf());
     AsyncJob::Start(cs);
 }
@@ -225,6 +226,8 @@
 // connection with the ICAP service established
 void Adaptation::Icap::Xaction::noteCommConnected(const CommConnectCbParams &io)
 {
+    cs = NULL;
+
     if (io.flag == COMM_TIMEOUT) {
         handleCommTimedout();
         return;
@@ -508,6 +511,12 @@
 void Adaptation::Icap::Xaction::swanSong()
 {
     // kids should sing first and then call the parent method.
+    if (cs) {
+        debugs(93,6, HERE << id << " about to notify ConnOpener!");
+        CallJobHere(93, 3, cs, Comm::ConnOpener, noteAbort);
+        cs = NULL;
+        service().noteConnectionFailed("abort");
+    }
 
     closeConnection(); // TODO: rename because we do not always close
 
diff -u -r -N squid-3.3.0.1/src/adaptation/icap/Xaction.h squid-3.3.0.2/src/adaptation/icap/Xaction.h
--- squid-3.3.0.1/src/adaptation/icap/Xaction.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/adaptation/icap/Xaction.h	2012-12-02 21:30:11.000000000 +1300
@@ -42,6 +42,10 @@
 #include "ipcache.h"
 
 class CommConnectCbParams;
+namespace Comm
+{
+class ConnOpener;
+}
 
 namespace Adaptation
 {
@@ -188,6 +192,7 @@
     timeval icap_tio_finish;   /*time when the last byte of the ICAP responsewas received*/
 
 private:
+    Comm::ConnOpener *cs;
     //CBDATA_CLASS2(Xaction);
 };
 
diff -u -r -N squid-3.3.0.1/src/base/TextException.cc squid-3.3.0.2/src/base/TextException.cc
--- squid-3.3.0.1/src/base/TextException.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/base/TextException.cc	2012-12-02 21:30:11.000000000 +1300
@@ -17,7 +17,7 @@
 }
 
 TextException::TextException(const char *aMsg, const char *aFileName, int aLineNo, unsigned int anId):
-        message(xstrdup(aMsg)), theFileName(aFileName), theLineNo(aLineNo), theId(anId)
+        message(aMsg?xstrdup(aMsg):NULL), theFileName(aFileName), theLineNo(aLineNo), theId(anId)
 {}
 
 TextException::~TextException() throw()
diff -u -r -N squid-3.3.0.1/src/cache_cf.cc squid-3.3.0.2/src/cache_cf.cc
--- squid-3.3.0.1/src/cache_cf.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/cache_cf.cc	2012-12-02 21:30:11.000000000 +1300
@@ -594,6 +594,7 @@
     cfg_filename = orig_cfg_filename;
     config_lineno = orig_config_lineno;
 
+    xfree(tmp_line);
     return err_count;
 }
 
diff -u -r -N squid-3.3.0.1/src/cf.data.pre squid-3.3.0.2/src/cf.data.pre
--- squid-3.3.0.1/src/cf.data.pre	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/cf.data.pre	2012-12-02 21:30:11.000000000 +1300
@@ -754,6 +754,8 @@
 
 	acl aclname url_regex [-i] ^http:// ...
 	  # regex matching on whole URL [fast]
+	acl aclname urllogin [-i] [^a-zA-Z0-9] ...
+	  # regex matching on URL login field
 	acl aclname urlpath_regex [-i] \.gif$ ...
 	  # regex matching on URL path [fast]
 
diff -u -r -N squid-3.3.0.1/src/cf_gen.cc squid-3.3.0.2/src/cf_gen.cc
--- squid-3.3.0.1/src/cf_gen.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/cf_gen.cc	2012-12-02 21:30:11.000000000 +1300
@@ -157,6 +157,7 @@
 static void gen_default_if_none(const EntryList &, std::ostream&);
 static void gen_default_postscriptum(const EntryList &, std::ostream&);
 static bool isDefined(const std::string &name);
+static const char *available_if(const std::string &name);
 
 static void
 checkDepend(const std::string &directive, const char *name, const TypeList &types, const EntryList &entries)
@@ -551,7 +552,9 @@
 {
     fout << "static void" << std::endl <<
     "defaults_if_none(void)" << std::endl <<
-    "{" << std::endl;
+    "{" << std::endl <<
+    "    cfg_filename = \"Default Configuration (if absent)\";" << std::endl <<
+    "    config_lineno = 0;" << std::endl;
 
     for (EntryList::const_iterator entry = head.begin(); entry != head.end(); ++entry) {
         assert(entry->name.size());
@@ -579,7 +582,8 @@
             fout << "#endif" << std::endl;
     }
 
-    fout << "}" << std::endl << std::endl;
+    fout << "    cfg_filename = NULL;" << std::endl <<
+    "}" << std::endl << std::endl;
 }
 
 /// append configuration options specified by POSTSCRIPTUM lines
@@ -588,7 +592,9 @@
 {
     fout << "static void" << std::endl <<
     "defaults_postscriptum(void)" << std::endl <<
-    "{" << std::endl;
+    "{" << std::endl <<
+    "    cfg_filename = \"Default Configuration (postscriptum)\";" << std::endl <<
+    "    config_lineno = 0;" << std::endl;
 
     for (EntryList::const_iterator entry = head.begin(); entry != head.end(); ++entry) {
         assert(entry->name.size());
@@ -609,13 +615,16 @@
             fout << "#endif" << std::endl;
     }
 
-    fout << "}" << std::endl << std::endl;
+    fout << "    cfg_filename = NULL;" << std::endl <<
+    "}" << std::endl << std::endl;
 }
 
 void
 Entry::genParseAlias(const std::string &aName, std::ostream &fout) const
 {
     fout << "    if (!strcmp(token, \"" << aName << "\")) {" << std::endl;
+    if (ifdef.size())
+        fout << "#if " << ifdef << std::endl;
     fout << "        ";
     if (type.compare("obsolete") == 0) {
         fout << "debugs(0, DBG_CRITICAL, \"ERROR: Directive '" << aName << "' is obsolete.\");\n";
@@ -630,6 +639,12 @@
         fout << "parse_" << type << "(&" << loc << (array_flag ? "[0]" : "") << ");";
     }
     fout << std::endl;
+    if (ifdef.size()) {
+        fout <<
+        "#else" << std::endl <<
+        "    debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), \"ERROR: '" << name << "' requires " << available_if(ifdef) << "\");" << std::endl <<
+        "#endif" << std::endl;
+    }
     fout << "        return 1;" << std::endl;
     fout << "    };" << std::endl;
 }
@@ -640,9 +655,6 @@
     if (name.compare("comment") == 0)
         return;
 
-    if (ifdef.size())
-        fout << "#if " << ifdef << std::endl;
-
     // Once for the current directive name
     genParseAlias(name, fout);
 
@@ -650,9 +662,6 @@
     for (EntryAliasList::const_iterator a = alias.begin(); a != alias.end(); ++a) {
         genParseAlias(*a, fout);
     }
-
-    if (ifdef.size())
-        fout << "#endif\n";
 }
 
 static void
diff -u -r -N squid-3.3.0.1/src/cf_gen_defines squid-3.3.0.2/src/cf_gen_defines
--- squid-3.3.0.1/src/cf_gen_defines	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/cf_gen_defines	2012-12-02 21:30:11.000000000 +1300
@@ -14,6 +14,7 @@
 	define["ICAP_CLIENT"]="--enable-icap-client"
 	define["SQUID_SNMP"]="--enable-snmp"
 	define["USE_ADAPTATION"]="--enable-ecap or --enable-icap-client"
+	define["USE_AUTH"]="--enable-auth"
 	define["USE_CACHE_DIGESTS"]="--enable-cache-digests"
 	define["USE_DNSHELPER"]="--disable-internal-dns"
 	define["!USE_DNSHELPER"]="--enable-internal-dns"
@@ -24,6 +25,8 @@
 	define["USE_IDENT"]="--enable-ident-lookups"
 	define["USE_LOADABLE_MODULES"]="--enable-loadable-modules"
 	define["USE_SQUID_ESI"]="--enable-esi"
+	define["USE_SQUID_EUI"]="--enable-eui"
+	define["USE_SSL_CRTD"]="--enable-ssl-crtd"
 	define["USE_SSL"]="--enable-ssl"
 	define["USE_UNLINKD"]="--enable-unlinkd"
 	define["USE_WCCP"]="--enable-wccp"
@@ -34,8 +37,8 @@
 }
 /^IFDEF:/ {
 	if (define[$2] != "")
-	    DEFINE=define[$2] " option"
-	else  
+	    DEFINE=define[$2]
+	else
 	    DEFINE="-D" $2 " define"
 	print "{\"" $2 "\", \"" DEFINE "\", "
 	print "#if " $2
diff -u -r -N squid-3.3.0.1/src/client_side_reply.cc squid-3.3.0.2/src/client_side_reply.cc
--- squid-3.3.0.1/src/client_side_reply.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/client_side_reply.cc	2012-12-02 21:30:11.000000000 +1300
@@ -1367,7 +1367,7 @@
         else if (http->storeEntry()->timestamp > 0)
             hdr->insertTime(HDR_DATE, http->storeEntry()->timestamp);
         else {
-            debugs(88,DBG_IMPORTANT,"WARNING: An error inside Squid has caused an HTTP reply without Date:. Please report this:");
+            debugs(88,DBG_IMPORTANT,"BUG 3279: HTTP reply without Date:");
             /* dump something useful about the problem */
             http->storeEntry()->dump(DBG_IMPORTANT);
         }
diff -u -r -N squid-3.3.0.1/src/comm/Connection.cc squid-3.3.0.2/src/comm/Connection.cc
--- squid-3.3.0.1/src/comm/Connection.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/comm/Connection.cc	2012-12-02 21:30:11.000000000 +1300
@@ -29,7 +29,7 @@
 Comm::Connection::~Connection()
 {
     if (fd >= 0) {
-        debugs(5, DBG_CRITICAL, "BUG: Orphan Comm::Connection: " << *this);
+        debugs(5, DBG_CRITICAL, "BUG #3329: Orphan Comm::Connection: " << *this);
         debugs(5, DBG_CRITICAL, "NOTE: " << ++lost_conn << " Orphans since last started.");
         close();
     }
diff -u -r -N squid-3.3.0.1/src/comm/ConnOpener.h squid-3.3.0.2/src/comm/ConnOpener.h
--- squid-3.3.0.1/src/comm/ConnOpener.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/comm/ConnOpener.h	2012-12-02 21:30:11.000000000 +1300
@@ -21,6 +21,8 @@
     virtual void swanSong();
 
 public:
+    void noteAbort() { mustStop("externally aborted"); }
+
     typedef CbcPointer<ConnOpener> Pointer;
 
     virtual bool doneAll() const;
diff -u -r -N squid-3.3.0.1/src/comm/TcpAcceptor.cc squid-3.3.0.2/src/comm/TcpAcceptor.cc
--- squid-3.3.0.1/src/comm/TcpAcceptor.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/comm/TcpAcceptor.cc	2012-12-02 21:30:11.000000000 +1300
@@ -53,11 +53,12 @@
 #if HAVE_ERRNO_H
 #include <errno.h>
 #endif
+#ifdef HAVE_NETINET_TCP_H
+// required for accept_filter to build.
+#include <netinet/tcp.h>
+#endif
 
-namespace Comm
-{
-CBDATA_CLASS_INIT(TcpAcceptor);
-};
+CBDATA_NAMESPACED_CLASS_INIT(Comm, TcpAcceptor);
 
 Comm::TcpAcceptor::TcpAcceptor(const Comm::ConnectionPointer &newConn, const char *note, const Subscription::Pointer &aSub) :
         AsyncJob("Comm::TcpAcceptor"),
diff -u -r -N squid-3.3.0.1/src/comm.cc squid-3.3.0.2/src/comm.cc
--- squid-3.3.0.1/src/comm.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/comm.cc	2012-12-02 21:30:11.000000000 +1300
@@ -233,7 +233,7 @@
 bool
 comm_monitors_read(int fd)
 {
-    assert(isOpen(fd));
+    assert(isOpen(fd) && COMMIO_FD_READCB(fd));
     // Being active is usually the same as monitoring because we always
     // start monitoring the FD when we configure Comm::IoCallback for I/O
     // and we usually configure Comm::IoCallback for I/O when we starting
@@ -362,7 +362,7 @@
 bool
 comm_has_incomplete_write(int fd)
 {
-    assert(isOpen(fd));
+    assert(isOpen(fd) && COMMIO_FD_WRITECB(fd));
     return COMMIO_FD_WRITECB(fd)->active();
 }
 
@@ -1235,7 +1235,7 @@
 void
 comm_remove_close_handler(int fd, CLCB * handler, void *data)
 {
-    assert (isOpen(fd));
+    assert(isOpen(fd));
     /* Find handler in list */
     debugs(5, 5, "comm_remove_close_handler: FD " << fd << ", handler=" <<
            handler << ", data=" << data);
@@ -1264,7 +1264,7 @@
 void
 comm_remove_close_handler(int fd, AsyncCall::Pointer &call)
 {
-    assert (isOpen(fd));
+    assert(isOpen(fd));
     debugs(5, 5, "comm_remove_close_handler: FD " << fd << ", AsyncCall=" << call);
 
     // comm_close removes all close handlers so our handler may be gone
@@ -1835,8 +1835,7 @@
 commStartHalfClosedMonitor(int fd)
 {
     debugs(5, 5, HERE << "adding FD " << fd << " to " << *TheHalfClosed);
-    assert(isOpen(fd));
-    assert(!commHasHalfClosedMonitor(fd));
+    assert(isOpen(fd) && !commHasHalfClosedMonitor(fd));
     (void)TheHalfClosed->add(fd); // could also assert the result
     commPlanHalfClosedCheck(); // may schedule check if we added the first FD
 }
@@ -2136,7 +2135,7 @@
         return -1;
     }
 
-    debugs(50, 3, HERE "Opened UDS FD " << new_socket << " : family=" << AI.ai_family << ", type=" << AI.ai_socktype << ", protocol=" << AI.ai_protocol);
+    debugs(50, 3, "Opened UDS FD " << new_socket << " : family=" << AI.ai_family << ", type=" << AI.ai_socktype << ", protocol=" << AI.ai_protocol);
 
     /* update fdstat */
     debugs(50, 5, HERE << "FD " << new_socket << " is a new socket");
diff -u -r -N squid-3.3.0.1/src/Debug.h squid-3.3.0.2/src/Debug.h
--- squid-3.3.0.1/src/Debug.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/Debug.h	2012-12-02 21:30:11.000000000 +1300
@@ -107,17 +107,28 @@
 #define debugs(SECTION, LEVEL, CONTENT) \
    do { \
         if ((Debug::level = (LEVEL)) <= Debug::Levels[SECTION]) { \
-                Debug::getDebugOut() << CONTENT; \
-                Debug::finishDebug(); \
+            std::ostream &_dbo=Debug::getDebugOut(); \
+            if (Debug::level > DBG_IMPORTANT) \
+                _dbo << SkipBuildPrefix(__FILE__)<<"("<<__LINE__<<") "<<__FUNCTION__<<": "; \
+            _dbo << CONTENT; \
+            Debug::finishDebug(); \
         } \
    } while (/*CONSTCOND*/ 0)
 
-/*
- * HERE is a macro that you can use like this:
+/** stream manipulator which does nothing.
+ * \deprecated Do not add to new code, and remove when editing old code
  *
+ * Its purpose is to inactivate calls made following previous debugs()
+ * guidelines such as
  * debugs(1,2, HERE << "some message");
+ *
+ * His former objective is now absorbed in the debugs call itself
  */
-#define HERE SkipBuildPrefix(__FILE__)<<"("<<__LINE__<<") "<<__FUNCTION__<<": "
+inline std::ostream&
+HERE(std::ostream& s)
+{
+    return s;
+}
 
 /*
  * MYNAME is for use at debug levels 0 and 1 where HERE is too messy.
diff -u -r -N squid-3.3.0.1/src/delay_pools.cc squid-3.3.0.2/src/delay_pools.cc
--- squid-3.3.0.1/src/delay_pools.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/delay_pools.cc	2012-12-02 21:30:11.000000000 +1300
@@ -368,7 +368,7 @@
     /* If we aren't active, don't try to update us ! */
     assert (rate.restore_bps != -1);
 
-    for (unsigned char j = 0; j < individuals.size(); ++j)
+    for (unsigned int j = 0; j < individuals.size(); ++j)
         individuals.values[j].update (rate, incr);
 }
 
diff -u -r -N squid-3.3.0.1/src/DiskIO/DiskDaemon/DiskdAction.cc squid-3.3.0.2/src/DiskIO/DiskDaemon/DiskdAction.cc
--- squid-3.3.0.1/src/DiskIO/DiskDaemon/DiskdAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/DiskIO/DiskDaemon/DiskdAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -15,7 +15,7 @@
 
 DiskdActionData::DiskdActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 DiskdActionData&
diff -u -r -N squid-3.3.0.1/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc squid-3.3.0.2/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc
--- squid-3.3.0.1/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc	2012-12-02 21:30:11.000000000 +1300
@@ -401,7 +401,8 @@
     } else {
         debugs(79, DBG_IMPORTANT, "storeDiskdSend: msgsnd: " << xstrerror());
         cbdataReferenceDone(M->callback_data);
-        assert(++send_errors < 100);
+        ++send_errors;
+        assert(send_errors < 100);
         if (shm_offset > -1)
             shm.put(shm_offset);
     }
diff -u -r -N squid-3.3.0.1/src/DiskIO/DiskThreads/aiops.cc squid-3.3.0.2/src/DiskIO/DiskThreads/aiops.cc
--- squid-3.3.0.1/src/DiskIO/DiskThreads/aiops.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/DiskIO/DiskThreads/aiops.cc	2012-12-02 21:30:11.000000000 +1300
@@ -306,6 +306,10 @@
 
     done_queue.blocked = 0;
 
+    // Initialize the thread I/O pipes before creating any threads
+    // see bug 3189 comment 5 about race conditions.
+    CommIO::Initialize();
+
     /* Create threads and get them to sit in their wait loop */
     squidaio_thread_pool = memPoolCreate("aio_thread", sizeof(squidaio_thread_t));
 
diff -u -r -N squid-3.3.0.1/src/DiskIO/DiskThreads/CommIO.cc squid-3.3.0.2/src/DiskIO/DiskThreads/CommIO.cc
--- squid-3.3.0.1/src/DiskIO/DiskThreads/CommIO.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/DiskIO/DiskThreads/CommIO.cc	2012-12-02 21:30:11.000000000 +1300
@@ -39,19 +39,22 @@
 #include "globals.h"
 
 void
-CommIO::Initialise()
+CommIO::Initialize()
 {
+    if (CommIO::Initialized)
+        return;
+
     /* Initialize done pipe signal */
     int DonePipe[2];
     if (pipe(DonePipe)) {}
     DoneFD = DonePipe[1];
     DoneReadFD = DonePipe[0];
-    fd_open(DoneReadFD, FD_PIPE, "async-io completetion event: main");
-    fd_open(DoneFD, FD_PIPE, "async-io completetion event: threads");
+    fd_open(DoneReadFD, FD_PIPE, "async-io completion event: main");
+    fd_open(DoneFD, FD_PIPE, "async-io completion event: threads");
     commSetNonBlocking(DoneReadFD);
     commSetNonBlocking(DoneFD);
     Comm::SetSelect(DoneReadFD, COMM_SELECT_READ, NULLFDHandler, NULL, 0);
-    Initialised = true;
+    Initialized = true;
 }
 
 void
@@ -63,10 +66,10 @@
     close(DoneReadFD);
     fd_close(DoneFD);
     fd_close(DoneReadFD);
-    Initialised = false;
+    Initialized = false;
 }
 
-bool CommIO::Initialised = false;
+bool CommIO::Initialized = false;
 bool CommIO::DoneSignalled = false;
 int CommIO::DoneFD = -1;
 int CommIO::DoneReadFD = -1;
diff -u -r -N squid-3.3.0.1/src/DiskIO/DiskThreads/CommIO.h squid-3.3.0.2/src/DiskIO/DiskThreads/CommIO.h
--- squid-3.3.0.1/src/DiskIO/DiskThreads/CommIO.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/DiskIO/DiskThreads/CommIO.h	2012-12-02 21:30:11.000000000 +1300
@@ -10,24 +10,25 @@
 public:
     static inline void NotifyIOCompleted();
     static void ResetNotifications();
-    static void Initialise();
+    static void Initialize();
     static void NotifyIOClose();
 
 private:
     static void NULLFDHandler(int, void *);
     static void FlushPipe();
-    static bool Initialised;
+    static bool Initialized;
     static bool DoneSignalled;
     static int DoneFD;
     static int DoneReadFD;
 };
 
-/* Inline code. TODO: make structued approach to inlining */
+/* Inline code. TODO: make structured approach to inlining */
 void
 CommIO::NotifyIOCompleted()
 {
-    if (!Initialised)
-        Initialise();
+    if (!Initialized) {
+        fatalf("Disk Threads I/O pipes not initialized before first use.");
+    }
 
     if (!DoneSignalled) {
         DoneSignalled = true;
diff -u -r -N squid-3.3.0.1/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc squid-3.3.0.2/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
--- squid-3.3.0.1/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc	2012-12-02 21:30:11.000000000 +1300
@@ -360,7 +360,8 @@
 
     debugs(79, 3, "DiskThreadsDiskFile::writeDone: FD " << fd << ", len " << len << ", err=" << errflag);
 
-    assert(++loop_detect < 10);
+    ++loop_detect;
+    assert(loop_detect < 10);
 
     --inProgressIOs;
 
diff -u -r -N squid-3.3.0.1/src/dns_internal.cc squid-3.3.0.2/src/dns_internal.cc
--- squid-3.3.0.1/src/dns_internal.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/dns_internal.cc	2012-12-02 21:30:11.000000000 +1300
@@ -334,7 +334,8 @@
     }
 
     assert(npc < npc_alloc);
-    strcpy(searchpath[npc].domain, buf);
+    strncpy(searchpath[npc].domain, buf, sizeof(searchpath[npc].domain)-1);
+    searchpath[npc].domain[sizeof(searchpath[npc].domain)-1] = '\0';
     Tolower(searchpath[npc].domain);
     debugs(78, 3, "idnsAddPathComponent: Added domain #" << npc << ": " << searchpath[npc].domain);
     ++npc;
diff -u -r -N squid-3.3.0.1/src/esi/Context.h squid-3.3.0.2/src/esi/Context.h
--- squid-3.3.0.1/src/esi/Context.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/Context.h	2012-12-02 21:30:11.000000000 +1300
@@ -50,7 +50,22 @@
     typedef RefCount<ESIContext> Pointer;
     void *operator new (size_t byteCount);
     void operator delete (void *address);
-    ESIContext():reading_(true) {}
+    ESIContext() :
+            thisNode(NULL),
+            http(NULL),
+            errorpage(ERR_NONE),
+            errorstatus(HTTP_STATUS_NONE),
+            errormessage(NULL),
+            rep(NULL),
+            outbound_offset(0),
+            readpos(0),
+            pos(0),
+            varState(NULL),
+            cachedASTInUse(false),
+            reading_(true),
+            processing(false) {
+        memset(&flags, 0, sizeof(flags));
+    }
 
     ~ESIContext();
 
diff -u -r -N squid-3.3.0.1/src/esi/CustomParser.cc squid-3.3.0.2/src/esi/CustomParser.cc
--- squid-3.3.0.1/src/esi/CustomParser.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/CustomParser.cc	2012-12-02 21:30:11.000000000 +1300
@@ -68,7 +68,9 @@
     return SearchTrie;
 }
 
-ESICustomParser::ESICustomParser(ESIParserClient *aClient) : theClient (aClient)
+ESICustomParser::ESICustomParser(ESIParserClient *aClient) :
+        theClient(aClient),
+        lastTag(ESITAG)
 {}
 
 ESICustomParser::~ESICustomParser()
@@ -190,7 +192,14 @@
                 }
 
                 char *value = equals + 1;
-                char *end = strchr (value, sep);
+                char *end = strchr(value, sep);
+
+                if (!end) {
+                    error = "Missing attribute ending separator (";
+                    error.append(sep);
+                    error.append(")");
+                    return false;
+                }
                 attributes.push_back(value);
                 *end = '\0';
                 attribute = end + 1;
diff -u -r -N squid-3.3.0.1/src/esi/Esi.cc squid-3.3.0.2/src/esi/Esi.cc
--- squid-3.3.0.1/src/esi/Esi.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/Esi.cc	2012-12-02 21:30:11.000000000 +1300
@@ -968,7 +968,10 @@
     return stack[stackdepth-1];
 }
 
-ESIContext::ParserState::ParserState() : inited_ (false)
+ESIContext::ParserState::ParserState() :
+        stackdepth(0),
+        parsing(0),
+        inited_(false)
 {}
 
 bool
@@ -1554,6 +1557,7 @@
 esiLiteral::esiLiteral(ESIContext *context, const char *s, int numberOfCharacters)
 {
     assert (s);
+    flags.donevars = 0;
     buffer = new ESISegment;
     ESISegment::Pointer local = buffer;
     size_t start = 0;
@@ -1570,7 +1574,7 @@
         remainingCharacters -= len;
     }
 
-    varState = cbdataReference (context->varState);
+    varState = cbdataReference(context->varState);
 }
 
 void
@@ -1705,11 +1709,15 @@
     debugs(86, 5, "esiTry::~esiTry " << this);
 }
 
-esiTry::esiTry(esiTreeParentPtr aParent) : parent (aParent) , exceptbuffer(NULL)
-{}
+esiTry::esiTry(esiTreeParentPtr aParent) :
+        parent(aParent),
+        exceptbuffer(NULL)
+{
+    memset(&flags, 0, sizeof(flags));
+}
 
 void
-esiTry::render (ESISegment::Pointer output)
+esiTry::render(ESISegment::Pointer output)
 {
     /* Try renders from it's children */
     assert (this);
@@ -2087,8 +2095,8 @@
         return;
 
     for (size_t counter = 0; counter < elements.size(); ++counter) {
-        if ((dynamic_cast<esiWhen *>(elements[counter].getRaw()))->
-                testsTrue()) {
+        const esiWhen *el = dynamic_cast<esiWhen *>(elements[counter].getRaw());
+        if (el && el->testsTrue()) {
             chosenelement = counter;
             debugs (86,3, "esiChooseAdd: Chose element " << counter + 1);
             return;
@@ -2325,9 +2333,12 @@
 }
 
 /* esiWhen */
-esiWhen::esiWhen (esiTreeParentPtr aParent, int attrcount, const char **attr,ESIVarState *aVar) : esiSequence (aParent)
+esiWhen::esiWhen(esiTreeParentPtr aParent, int attrcount, const char **attr,ESIVarState *aVar) :
+        esiSequence(aParent),
+        testValue(false),
+        unevaluatedExpression(NULL),
+        varState(NULL)
 {
-    varState = NULL;
     char const *expression = NULL;
 
     for (int loopCounter = 0; loopCounter < attrcount && attr[loopCounter]; loopCounter += 2) {
@@ -2370,7 +2381,7 @@
     if (!unevaluatedExpression)
         return;
 
-    assert (varState);
+    assert(varState);
 
     varState->feedData(unevaluatedExpression, strlen (unevaluatedExpression));
 
@@ -2381,14 +2392,14 @@
     safe_free (expression);
 }
 
-esiWhen::esiWhen(esiWhen const &old) : esiSequence (old)
+esiWhen::esiWhen(esiWhen const &old) :
+        esiSequence(old),
+        testValue(false),
+        unevaluatedExpression(NULL),
+        varState(NULL)
 {
-    unevaluatedExpression = NULL;
-
     if (old.unevaluatedExpression)
         unevaluatedExpression = xstrdup(old.unevaluatedExpression);
-
-    varState = NULL;
 }
 
 ESIElement::Pointer
diff -u -r -N squid-3.3.0.1/src/esi/Expression.cc squid-3.3.0.2/src/esi/Expression.cc
--- squid-3.3.0.1/src/esi/Expression.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/Expression.cc	2012-12-02 21:30:11.000000000 +1300
@@ -293,10 +293,6 @@
 
     rv = stack[whereAmI - 1].value.integral || stack[whereAmI + 1].value.integral;
 
-    if (rv == -2)
-        /* invalid comparison */
-        return 1;
-
     stackpop(stack, depth);      /* arg rhs */
 
     stackpop(stack, depth);      /* me */
@@ -344,10 +340,6 @@
 
     rv = stack[whereAmI - 1].value.integral && stack[whereAmI + 1].value.integral;
 
-    if (rv == -2)
-        /* invalid comparison */
-        return 1;
-
     stackpop(stack, depth);      /* arg rhs */
 
     stackpop(stack, depth);      /* me */
diff -u -r -N squid-3.3.0.1/src/esi/Include.cc squid-3.3.0.2/src/esi/Include.cc
--- squid-3.3.0.1/src/esi/Include.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/Include.cc	2012-12-02 21:30:11.000000000 +1300
@@ -299,9 +299,15 @@
     return result;
 }
 
-ESIInclude::ESIInclude(ESIInclude const &old) : parent (NULL), started (false), sent (false)
+ESIInclude::ESIInclude(ESIInclude const &old) :
+        varState(NULL),
+        srcurl(NULL),
+        alturl(NULL),
+        parent(NULL),
+        started(false),
+        sent(false)
 {
-    varState = NULL;
+    memset(&flags, 0, sizeof(flags));
     flags.onerrorcontinue = old.flags.onerrorcontinue;
 
     if (old.srcurl)
@@ -344,12 +350,18 @@
     tempheaders.clean();
 }
 
-ESIInclude::ESIInclude (esiTreeParentPtr aParent, int attrcount, char const **attr, ESIContext *aContext) : parent (aParent), started (false), sent (false)
+ESIInclude::ESIInclude(esiTreeParentPtr aParent, int attrcount, char const **attr, ESIContext *aContext) :
+        varState(NULL),
+        srcurl(NULL),
+        alturl(NULL),
+        parent(aParent),
+        started(false),
+        sent(false)
 {
-    int i;
     assert (aContext);
+    memset(&flags, 0, sizeof(flags));
 
-    for (i = 0; i < attrcount && attr[i]; i += 2) {
+    for (int i = 0; i < attrcount && attr[i]; i += 2) {
         if (!strcmp(attr[i],"src")) {
             /* Start a request for thisNode url */
             debugs(86, 5, "ESIIncludeNew: Requesting source '" << attr[i+1] << "'");
diff -u -r -N squid-3.3.0.1/src/esi/Sequence.cc squid-3.3.0.2/src/esi/Sequence.cc
--- squid-3.3.0.1/src/esi/Sequence.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/Sequence.cc	2012-12-02 21:30:11.000000000 +1300
@@ -52,8 +52,19 @@
     debugs(86, 5, "esiSequence::~esiSequence " << this);
 }
 
-esiSequence::esiSequence(esiTreeParentPtr aParent, bool incrementalFlag) : elements(), parent (aParent), mayFail_(true), failed (false), provideIncrementalData (incrementalFlag), processing (false), processingResult (ESI_PROCESS_COMPLETE), nextElementToProcess_ (0)
-{}
+esiSequence::esiSequence(esiTreeParentPtr aParent, bool incrementalFlag) :
+        elements(),
+        processedcount(0),
+        parent(aParent),
+        mayFail_(true),
+        failed(false),
+        provideIncrementalData(incrementalFlag),
+        processing(false),
+        processingResult(ESI_PROCESS_COMPLETE),
+        nextElementToProcess_(0)
+{
+    memset(&flags, 0, sizeof(flags));
+}
 
 size_t
 esiSequence::nextElementToProcess() const
@@ -329,11 +340,17 @@
     parent = NULL;
 }
 
-esiSequence::esiSequence(esiSequence const &old)
-        : processedcount (0), mayFail_(old.mayFail_), failed (old.failed), provideIncrementalData (old.provideIncrementalData), processing (false), nextElementToProcess_ (0)
+esiSequence::esiSequence(esiSequence const &old) :
+        processedcount(0),
+        parent(NULL),
+        mayFail_(old.mayFail_),
+        failed(old.failed),
+        provideIncrementalData(old.provideIncrementalData),
+        processing(false),
+        processingResult(ESI_PROCESS_COMPLETE),
+        nextElementToProcess_(0)
 {
     flags.dovars = old.flags.dovars;
-    parent = NULL;
 }
 
 void
diff -u -r -N squid-3.3.0.1/src/esi/VarState.cc squid-3.3.0.2/src/esi/VarState.cc
--- squid-3.3.0.1/src/esi/VarState.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/esi/VarState.cc	2012-12-02 21:30:11.000000000 +1300
@@ -291,9 +291,12 @@
     safe_free (query_string);
 }
 
-ESIVarState::ESIVarState (HttpHeader const *aHeader, char const *uri)
-        : output (NULL), hdr(hoReply)
+ESIVarState::ESIVarState(HttpHeader const *aHeader, char const *uri) :
+        output(NULL),
+        hdr(hoReply)
 {
+    memset(&flags, 0, sizeof(flags));
+
     /* TODO: only grab the needed headers */
     /* Note that as we pass these through to included requests, we
      * cannot trim them */
diff -u -r -N squid-3.3.0.1/src/eui/Eui48.cc squid-3.3.0.2/src/eui/Eui48.cc
--- squid-3.3.0.1/src/eui/Eui48.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/eui/Eui48.cc	2012-12-02 21:30:11.000000000 +1300
@@ -176,6 +176,11 @@
 
     /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */
     int tmpSocket = socket(AF_INET,SOCK_STREAM,0);
+    if (tmpSocket < 0) {
+        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerror());
+        clear();
+        return false;
+    }
 
     /*
      * The linux kernel 2.2 maintains per interface ARP caches and
@@ -315,6 +320,11 @@
 
     /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */
     int tmpSocket = socket(AF_INET,SOCK_STREAM,0);
+    if (tmpSocket < 0) {
+        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerror());
+        clear();
+        return false;
+    }
 
     /* Set up structures for ARP lookup with blank interface name */
     struct arpreq arpReq;
diff -u -r -N squid-3.3.0.1/src/fs/ufs/UFSSwapDir.cc squid-3.3.0.2/src/fs/ufs/UFSSwapDir.cc
--- squid-3.3.0.1/src/fs/ufs/UFSSwapDir.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/fs/ufs/UFSSwapDir.cc	2012-12-02 21:30:11.000000000 +1300
@@ -809,27 +809,26 @@
 void
 Fs::Ufs::UFSSwapDir::closeTmpSwapLog()
 {
-    char *swaplog_path = xstrdup(logFile(NULL));
-    char *new_path = xstrdup(logFile(".new"));
+    char *swaplog_path = xstrdup(logFile(NULL)); // where the swaplog should be
+    char *tmp_path = xstrdup(logFile(".new")); // the temporary file we have generated
     int fd;
     file_close(swaplog_fd);
 
-    if (xrename(new_path, swaplog_path) < 0) {
-        debugs(50, DBG_IMPORTANT, HERE << "ERROR: " << swaplog_path << ": " << xstrerror());
-        fatalf("Failed to rename log file %s to %s.new", swaplog_path, swaplog_path);
+    if (xrename(tmp_path, swaplog_path) < 0) {
+        fatalf("Failed to rename log file %s to %s", tmp_path, swaplog_path);
     }
 
     fd = file_open(swaplog_path, O_WRONLY | O_CREAT | O_BINARY);
 
     if (fd < 0) {
-        debugs(50, DBG_IMPORTANT, HERE << "ERROR: " << swaplog_path << ": " << xstrerror());
+        debugs(50, DBG_IMPORTANT, "ERROR: " << swaplog_path << ": " << xstrerror());
         fatalf("Failed to open swap log %s", swaplog_path);
     }
 
-    safe_free(swaplog_path);
-    safe_free(new_path);
+    xfree(swaplog_path);
+    xfree(tmp_path);
     swaplog_fd = fd;
-    debugs(47, 3, HERE << "Cache Dir #" << index << " log opened on FD " << fd);
+    debugs(47, 3, "Cache Dir #" << index << " log opened on FD " << fd);
 }
 
 FILE *
@@ -846,7 +845,7 @@
     int fd;
 
     if (::stat(swaplog_path, &log_sb) < 0) {
-        debugs(47, DBG_IMPORTANT, HERE << "Cache Dir #" << index << ": No log file");
+        debugs(47, DBG_IMPORTANT, "Cache Dir #" << index << ": No log file");
         safe_free(swaplog_path);
         safe_free(clean_path);
         safe_free(new_path);
@@ -864,7 +863,7 @@
 
     if (fd < 0) {
         debugs(50, DBG_IMPORTANT, "ERROR: while opening swap log" << new_path << ": " << xstrerror());
-        fatal("UFSSwapDir::openTmpSwapLog: Failed to open swap log.");
+        fatalf("Failed to open swap log %s", new_path);
     }
 
     swaplog_fd = fd;
@@ -886,7 +885,7 @@
 
     if (fp == NULL) {
         debugs(50, DBG_CRITICAL, "ERROR: while opening " << swaplog_path << ": " << xstrerror());
-        fatal("Failed to open swap log for reading");
+        fatalf("Failed to open swap log for reading %s", swaplog_path);
     }
 
     memset(&clean_sb, '\0', sizeof(struct stat));
diff -u -r -N squid-3.3.0.1/src/http.cc squid-3.3.0.2/src/http.cc
--- squid-3.3.0.1/src/http.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/http.cc	2012-12-02 21:30:11.000000000 +1300
@@ -409,25 +409,28 @@
             return 0;
         }
 
-        // HTTPbis pt7 section 4.1 clause 3: a response CC:public is present
         bool mayStore = false;
+        // HTTPbis pt6 section 3.2: a response CC:public is present
         if (rep->cache_control->Public()) {
             debugs(22, 3, HERE << "Authenticated but server reply Cache-Control:public");
             mayStore = true;
 
-            // HTTPbis pt7 section 4.1 clause 2: a response CC:must-revalidate is present
+            // HTTPbis pt6 section 3.2: a response CC:must-revalidate is present
         } else if (rep->cache_control->mustRevalidate() && !REFRESH_OVERRIDE(ignore_must_revalidate)) {
             debugs(22, 3, HERE << "Authenticated but server reply Cache-Control:public");
             mayStore = true;
 
-#if 0 // waiting on HTTPbis WG agreement before we do this
+#if USE_HTTP_VIOLATIONS
             // NP: given the must-revalidate exception we should also be able to exempt no-cache.
-        } else if (rep->cache_control->noCache()) {
-            debugs(22, 3, HERE << "Authenticated but server reply Cache-Control:no-cache");
+            // HTTPbis WG verdict on this is that it is omitted from the spec due to being 'unexpected' by
+            // some. The caching+revalidate is not exactly unsafe though with Squids interpretation of no-cache
+            // as equivalent to must-revalidate in the reply.
+        } else if (rep->cache_control->noCache() && !REFRESH_OVERRIDE(ignore_must_revalidate)) {
+            debugs(22, 3, HERE << "Authenticated but server reply Cache-Control:no-cache (equivalent to must-revalidate)");
             mayStore = true;
 #endif
 
-            // HTTPbis pt7 section 4.1 clause 1: a response CC:s-maxage is present
+            // HTTPbis pt6 section 3.2: a response CC:s-maxage is present
         } else if (rep->cache_control->sMaxAge()) {
             debugs(22, 3, HERE << " Authenticated but server reply Cache-Control:s-maxage");
             mayStore = true;
diff -u -r -N squid-3.3.0.1/src/HttpHeader.cc squid-3.3.0.2/src/HttpHeader.cc
--- squid-3.3.0.1/src/HttpHeader.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/HttpHeader.cc	2012-12-02 21:30:11.000000000 +1300
@@ -1020,11 +1020,20 @@
 }
 
 /*
- * Returns the value of the specified header.
+ * Returns the value of the specified header and/or an undefined String.
  */
 String
 HttpHeader::getByName(const char *name) const
 {
+    String result;
+    // ignore presence: return undefined string if an empty header is present
+    (void)getByNameIfPresent(name, result);
+    return result;
+}
+
+bool
+HttpHeader::getByNameIfPresent(const char *name, String &result) const
+{
     http_hdr_type id;
     HttpHeaderPos pos = HttpHeaderInitPos;
     HttpHeaderEntry *e;
@@ -1034,19 +1043,23 @@
     /* First try the quick path */
     id = httpHeaderIdByNameDef(name, strlen(name));
 
-    if (id != -1)
-        return getStrOrList(id);
-
-    String result;
+    if (id != -1) {
+        if (!has(id))
+            return false;
+        result = getStrOrList(id);
+        return true;
+    }
 
     /* Sorry, an unknown header name. Do linear search */
+    bool found = false;
     while ((e = getEntry(&pos))) {
         if (e->id == HDR_OTHER && e->name.caseCmp(name) == 0) {
+            found = true;
             strListAdd(&result, e->value.termedBuf(), ',');
         }
     }
 
-    return result;
+    return found;
 }
 
 /*
diff -u -r -N squid-3.3.0.1/src/HttpHeader.h squid-3.3.0.2/src/HttpHeader.h
--- squid-3.3.0.1/src/HttpHeader.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/HttpHeader.h	2012-12-02 21:30:11.000000000 +1300
@@ -246,6 +246,8 @@
     bool getList(http_hdr_type id, String *s) const;
     String getStrOrList(http_hdr_type id) const;
     String getByName(const char *name) const;
+    /// sets value and returns true iff a [possibly empty] named field is there
+    bool getByNameIfPresent(const char *name, String &value) const;
     String getByNameListMember(const char *name, const char *member, const char separator) const;
     String getListMember(http_hdr_type id, const char *member, const char separator) const;
     int has(http_hdr_type id) const;
diff -u -r -N squid-3.3.0.1/src/icmp/pinger.cc squid-3.3.0.2/src/icmp/pinger.cc
--- squid-3.3.0.1/src/icmp/pinger.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/icmp/pinger.cc	2012-12-02 21:30:11.000000000 +1300
@@ -179,8 +179,18 @@
     }
     max_fd = max(max_fd, squid_link);
 
-    setgid(getgid());
-    setuid(getuid());
+    if (setgid(getgid()) < 0) {
+        debugs(42, DBG_CRITICAL, "FATAL: pinger: setgid(" << getgid() << ") failed: " << xstrerror());
+        icmp4.Close();
+        icmp6.Close();
+        exit (1);
+    }
+    if (setuid(getuid()) < 0) {
+        debugs(42, DBG_CRITICAL, "FATAL: pinger: setuid(" << getuid() << ") failed: " << xstrerror());
+        icmp4.Close();
+        icmp6.Close();
+        exit (1);
+    }
 
     last_check_time = squid_curtime;
 
diff -u -r -N squid-3.3.0.1/src/ipc/SharedListen.cc squid-3.3.0.2/src/ipc/SharedListen.cc
--- squid-3.3.0.1/src/ipc/SharedListen.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/ipc/SharedListen.cc	2012-12-02 21:30:11.000000000 +1300
@@ -45,7 +45,7 @@
 
 Ipc::OpenListenerParams::OpenListenerParams()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 bool
diff -u -r -N squid-3.3.0.1/src/ipc/StoreMap.cc squid-3.3.0.2/src/ipc/StoreMap.cc
--- squid-3.3.0.1/src/ipc/StoreMap.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/ipc/StoreMap.cc	2012-12-02 21:30:11.000000000 +1300
@@ -270,8 +270,8 @@
 
 Ipc::StoreMapSlot::StoreMapSlot(): state(Empty)
 {
-    xmemset(&key, 0, sizeof(key));
-    xmemset(&basics, 0, sizeof(basics));
+    memset(&key, 0, sizeof(key));
+    memset(&basics, 0, sizeof(basics));
 }
 
 void
diff -u -r -N squid-3.3.0.1/src/ipc/TypedMsgHdr.cc squid-3.3.0.2/src/ipc/TypedMsgHdr.cc
--- squid-3.3.0.1/src/ipc/TypedMsgHdr.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/ipc/TypedMsgHdr.cc	2012-12-02 21:30:11.000000000 +1300
@@ -12,7 +12,7 @@
 
 Ipc::TypedMsgHdr::TypedMsgHdr()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
     sync();
 }
 
@@ -204,7 +204,7 @@
 void
 Ipc::TypedMsgHdr::prepForReading()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
     allocName();
     allocData();
     allocControl();
diff -u -r -N squid-3.3.0.1/src/main.cc squid-3.3.0.2/src/main.cc
--- squid-3.3.0.1/src/main.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/main.cc	2012-12-02 21:30:11.000000000 +1300
@@ -543,6 +543,7 @@
             /** \par l
              * Stores the syslog facility name in global opt_syslog_facility
              * then performs actions for -s option. */
+            xfree(opt_syslog_facility); // ignore any previous options sent
             opt_syslog_facility = xstrdup(optarg);
 
         case 's':
diff -u -r -N squid-3.3.0.1/src/MemBlob.cc squid-3.3.0.2/src/MemBlob.cc
--- squid-3.3.0.1/src/MemBlob.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/MemBlob.cc	2012-12-02 21:30:11.000000000 +1300
@@ -43,7 +43,7 @@
 
 /* MemBlobStats */
 
-MemBlobStats::MemBlobStats(): alloc(0), live(0), append(0)
+MemBlobStats::MemBlobStats(): alloc(0), live(0), append(0), liveBytes(0)
 {}
 
 std::ostream&
diff -u -r -N squid-3.3.0.1/src/mgr/ActionPasswordList.cc squid-3.3.0.2/src/mgr/ActionPasswordList.cc
--- squid-3.3.0.1/src/mgr/ActionPasswordList.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/ActionPasswordList.cc	2012-12-02 21:30:11.000000000 +1300
@@ -29,4 +29,11 @@
 
 #include "squid.h"
 #include "mgr/ActionPasswordList.h"
+#include "wordlist.h"
 
+Mgr::ActionPasswordList::~ActionPasswordList()
+{
+    safe_free(passwd);
+    wordlistDestroy(&actions);
+    delete next;
+}
diff -u -r -N squid-3.3.0.1/src/mgr/ActionPasswordList.h squid-3.3.0.2/src/mgr/ActionPasswordList.h
--- squid-3.3.0.1/src/mgr/ActionPasswordList.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/ActionPasswordList.h	2012-12-02 21:30:11.000000000 +1300
@@ -38,6 +38,9 @@
 class ActionPasswordList
 {
 public:
+    ActionPasswordList() : passwd(NULL), actions(NULL), next(NULL) {}
+    ~ActionPasswordList();
+
     char *passwd;
     wordlist *actions;
     ActionPasswordList *next;
diff -u -r -N squid-3.3.0.1/src/mgr/CountersAction.cc squid-3.3.0.2/src/mgr/CountersAction.cc
--- squid-3.3.0.1/src/mgr/CountersAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/CountersAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -17,7 +17,7 @@
 
 Mgr::CountersActionData::CountersActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Mgr::CountersActionData&
diff -u -r -N squid-3.3.0.1/src/mgr/InfoAction.cc squid-3.3.0.2/src/mgr/InfoAction.cc
--- squid-3.3.0.1/src/mgr/InfoAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/InfoAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -25,7 +25,7 @@
 
 Mgr::InfoActionData::InfoActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Mgr::InfoActionData&
diff -u -r -N squid-3.3.0.1/src/mgr/IntervalAction.cc squid-3.3.0.2/src/mgr/IntervalAction.cc
--- squid-3.3.0.1/src/mgr/IntervalAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/IntervalAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -17,7 +17,7 @@
 
 Mgr::IntervalActionData::IntervalActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Mgr::IntervalActionData&
diff -u -r -N squid-3.3.0.1/src/mgr/IoAction.cc squid-3.3.0.2/src/mgr/IoAction.cc
--- squid-3.3.0.1/src/mgr/IoAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/IoAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -18,7 +18,7 @@
 
 Mgr::IoActionData::IoActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Mgr::IoActionData&
diff -u -r -N squid-3.3.0.1/src/mgr/ServiceTimesAction.cc squid-3.3.0.2/src/mgr/ServiceTimesAction.cc
--- squid-3.3.0.1/src/mgr/ServiceTimesAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/ServiceTimesAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -16,7 +16,7 @@
 
 Mgr::ServiceTimesActionData::ServiceTimesActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Mgr::ServiceTimesActionData&
diff -u -r -N squid-3.3.0.1/src/mgr/StoreIoAction.cc squid-3.3.0.2/src/mgr/StoreIoAction.cc
--- squid-3.3.0.1/src/mgr/StoreIoAction.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/mgr/StoreIoAction.cc	2012-12-02 21:30:11.000000000 +1300
@@ -13,7 +13,7 @@
 
 Mgr::StoreIoActionData::StoreIoActionData()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Mgr::StoreIoActionData&
diff -u -r -N squid-3.3.0.1/src/neighbors.cc squid-3.3.0.2/src/neighbors.cc
--- squid-3.3.0.1/src/neighbors.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/neighbors.cc	2012-12-02 21:30:11.000000000 +1300
@@ -846,7 +846,7 @@
 {
 #if USE_CACHE_DIGESTS
     if (p)
-        strncpy(request->hier.cd_host, p->host, sizeof(request->hier.cd_host));
+        strncpy(request->hier.cd_host, p->host, sizeof(request->hier.cd_host)-1);
     else
         *request->hier.cd_host = '\0';
 
diff -u -r -N squid-3.3.0.1/src/PeerDigest.h squid-3.3.0.2/src/PeerDigest.h
--- squid-3.3.0.1/src/PeerDigest.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/PeerDigest.h	2012-12-02 21:30:11.000000000 +1300
@@ -61,7 +61,10 @@
     int reserved[32 - 6];
 };
 
+class HttpRequest;
 class PeerDigest;
+class store_client;
+
 class DigestFetchState
 {
 public:
diff -u -r -N squid-3.3.0.1/src/snmp/Pdu.cc squid-3.3.0.2/src/snmp/Pdu.cc
--- squid-3.3.0.1/src/snmp/Pdu.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/snmp/Pdu.cc	2012-12-02 21:30:11.000000000 +1300
@@ -41,7 +41,7 @@
 void
 Snmp::Pdu::init()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
     errstat = SNMP_DEFAULT_ERRSTAT;
     errindex = SNMP_DEFAULT_ERRINDEX;
 }
diff -u -r -N squid-3.3.0.1/src/snmp/Session.cc squid-3.3.0.2/src/snmp/Session.cc
--- squid-3.3.0.1/src/snmp/Session.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/snmp/Session.cc	2012-12-02 21:30:11.000000000 +1300
@@ -35,7 +35,7 @@
 void
 Snmp::Session::clear()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 void
diff -u -r -N squid-3.3.0.1/src/snmp/Var.cc squid-3.3.0.2/src/snmp/Var.cc
--- squid-3.3.0.1/src/snmp/Var.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/snmp/Var.cc	2012-12-02 21:30:11.000000000 +1300
@@ -40,7 +40,7 @@
 void
 Snmp::Var::init()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 Snmp::Var&
diff -u -r -N squid-3.3.0.1/src/ssl/certificate_db.cc squid-3.3.0.2/src/ssl/certificate_db.cc
--- squid-3.3.0.1/src/ssl/certificate_db.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/ssl/certificate_db.cc	2012-12-02 21:30:11.000000000 +1300
@@ -103,19 +103,38 @@
 Ssl::CertificateDb::Row::Row()
         :   width(cnlNumber)
 {
-    row = new char *[width + 1];
+    row = (char **)OPENSSL_malloc(sizeof(char *) * (width + 1));
     for (size_t i = 0; i < width + 1; ++i)
         row[i] = NULL;
 }
 
+Ssl::CertificateDb::Row::Row(char **aRow, size_t aWidth): width(aWidth)
+{
+    row = aRow;
+}
+
 Ssl::CertificateDb::Row::~Row()
 {
-    if (row) {
+    if (!row)
+        return;
+
+    void *max;
+    if ((max = (void *)row[width]) != NULL) {
+        // It is an openSSL allocated row. The TXT_DB_read function stores the
+        // index and row items one one memory segment. The row[width] points
+        // to the end of buffer. We have to check for items in the array which
+        // are not stored in this segment. These items should released.
         for (size_t i = 0; i < width + 1; ++i) {
-            delete[](row[i]);
+            if (((row[i] < (char *)row) || (row[i] > max)) && (row[i] != NULL))
+                OPENSSL_free(row[i]);
+        }
+    } else {
+        for (size_t i = 0; i < width + 1; ++i) {
+            if (row[i])
+                OPENSSL_free(row[i]);
         }
-        delete[](row);
     }
+    OPENSSL_free(row);
 }
 
 void Ssl::CertificateDb::Row::reset()
@@ -130,7 +149,7 @@
         free(row[cell]);
     }
     if (value) {
-        row[cell] = static_cast<char *>(malloc(sizeof(char) * (strlen(value) + 1)));
+        row[cell] = static_cast<char *>(OPENSSL_malloc(sizeof(char) * (strlen(value) + 1)));
         memcpy(row[cell], value, sizeof(char) * (strlen(value) + 1));
     } else
         row[cell] = NULL;
@@ -141,6 +160,55 @@
     return row;
 }
 
+void Ssl::CertificateDb::sq_TXT_DB_delete(TXT_DB *db, const char **row)
+{
+    if (!db)
+        return;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+    for (int i = 0; i < sk_OPENSSL_PSTRING_num(db->data); ++i) {
+        const char ** current_row = ((const char **)sk_OPENSSL_PSTRING_value(db->data, i));
+#else
+    for (int i = 0; i < sk_num(db->data); ++i) {
+        const char ** current_row = ((const char **)sk_value(db->data, i));
+#endif
+        if (current_row == row) {
+            sq_TXT_DB_delete_row(db, i);
+            return;
+        }
+    }
+}
+
+#define countof(arr) (sizeof(arr)/sizeof(*arr))
+void Ssl::CertificateDb::sq_TXT_DB_delete_row(TXT_DB *db, int idx)
+{
+    char **rrow;
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+    rrow = (char **)sk_OPENSSL_PSTRING_delete(db->data, idx);
+#else
+    rrow = (char **)sk_delete(db->data, idx);
+#endif
+
+    if (!rrow)
+        return;
+
+    Row row(rrow, cnlNumber); // row wrapper used to free the rrow
+
+    const Columns db_indexes[]={cnlSerial, cnlName};
+    for (unsigned int i = 0; i < countof(db_indexes); ++i) {
+        void *data = NULL;
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+        if (LHASH_OF(OPENSSL_STRING) *fieldIndex =  db->index[db_indexes[i]])
+            data = lh_OPENSSL_STRING_delete(fieldIndex, rrow);
+#else
+        if (LHASH *fieldIndex = db->index[db_indexes[i]])
+            data = lh_delete(fieldIndex, rrow);
+#endif
+        if (data)
+            assert(data == rrow);
+    }
+}
+
 unsigned long Ssl::CertificateDb::index_serial_hash(const char **a)
 {
     const char *n = a[Ssl::CertificateDb::cnlSerial];
@@ -227,13 +295,24 @@
     char ** rrow = TXT_DB_get_by_index(db.get(), cnlSerial, row.getRow());
     // We are creating certificates with unique serial numbers. If the serial
     // number is found in the database, the same certificate is already stored.
-    if (rrow != NULL)
+    if (rrow != NULL) {
+        // TODO: check if the stored row is valid.
         return true;
+    }
 
     {
         TidyPointer<char, tidyFree> subject(X509_NAME_oneline(X509_get_subject_name(cert.get()), NULL, 0));
-        if (pure_find(useName.empty() ? subject.get() : useName, cert, pkey))
+        Ssl::X509_Pointer findCert;
+        Ssl::EVP_PKEY_Pointer findPkey;
+        if (pure_find(useName.empty() ? subject.get() : useName, findCert, findPkey)) {
+            // Replace with database certificate
+            cert.reset(findCert.release());
+            pkey.reset(findPkey.release());
             return true;
+        }
+        // pure_find may fail because the entry is expired, or because the
+        // certs file is corrupted. Remove any entry with given hostname
+        deleteByHostname(useName.empty() ? subject.get() : useName);
     }
 
     // check db size while trying to minimize calls to size()
@@ -243,8 +322,10 @@
 
         // there are no more invalid ones, but there must be valid certificates
         do {
-            if (!deleteOldestCertificate())
+            if (!deleteOldestCertificate()) {
+                save(); // Some entries may have been removed. Update the index file.
                 return false; // errors prevented us from freeing enough space
+            }
         } while (size() > max_db_size);
         break;
     }
@@ -260,13 +341,22 @@
         row.setValue(cnlName, subject.get());
     }
 
-    if (!TXT_DB_insert(db.get(), row.getRow()))
+    if (!TXT_DB_insert(db.get(), row.getRow())) {
+        // failed to add index (???) but we may have already modified
+        // the database so save before exit
+        save();
         return false;
-
+    }
+    rrow = row.getRow();
     row.reset();
+
     std::string filename(cert_full + "/" + serial_string + ".pem");
-    if (!writeCertAndPrivateKeyToFile(cert, pkey, filename.c_str()))
+    if (!writeCertAndPrivateKeyToFile(cert, pkey, filename.c_str())) {
+        //remove row from txt_db and save
+        sq_TXT_DB_delete(db.get(), (const char **)rrow);
+        save();
         return false;
+    }
     addSize(filename);
 
     save();
@@ -315,10 +405,8 @@
     if (rrow == NULL)
         return false;
 
-    if (!sslDateIsInTheFuture(rrow[cnlExp_date])) {
-        deleteByHostname(rrow[cnlName]);
+    if (!sslDateIsInTheFuture(rrow[cnlExp_date]))
         return false;
-    }
 
     // read cert and pkey from file.
     std::string filename(cert_full + "/" + rrow[cnlSerial] + ".pem");
@@ -418,26 +506,10 @@
 }
 
 // Normally defined in defines.h file
-#define countof(arr) (sizeof(arr)/sizeof(*arr))
 void Ssl::CertificateDb::deleteRow(const char **row, int rowIndex)
 {
     const std::string filename(cert_full + "/" + row[cnlSerial] + ".pem");
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-    sk_OPENSSL_PSTRING_delete(db.get()->data, rowIndex);
-#else
-    sk_delete(db.get()->data, rowIndex);
-#endif
-
-    const Columns db_indexes[]={cnlSerial, cnlName};
-    for (unsigned int i = 0; i < countof(db_indexes); ++i) {
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-        if (LHASH_OF(OPENSSL_STRING) *fieldIndex =  db.get()->index[db_indexes[i]])
-            lh_OPENSSL_STRING_delete(fieldIndex, (char **)row);
-#else
-        if (LHASH *fieldIndex = db.get()->index[db_indexes[i]])
-            lh_delete(fieldIndex, row);
-#endif
-    }
+    sq_TXT_DB_delete_row(db.get(), rowIndex);
 
     subSize(filename);
     int ret = remove(filename.c_str());
diff -u -r -N squid-3.3.0.1/src/ssl/certificate_db.h squid-3.3.0.2/src/ssl/certificate_db.h
--- squid-3.3.0.1/src/ssl/certificate_db.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/ssl/certificate_db.h	2012-12-02 21:30:11.000000000 +1300
@@ -77,6 +77,8 @@
     public:
         /// Create row wrapper.
         Row();
+        ///Create row wrapper for row with width items
+        Row(char **row, size_t width);
         /// Delete all row.
         ~Row();
         void setValue(size_t number, char const * value); ///< Set cell's value in row
@@ -118,6 +120,11 @@
     bool deleteOldestCertificate(); ///< Delete oldest certificate.
     bool deleteByHostname(std::string const & host); ///< Delete using host name.
 
+    /// Removes the first matching row from TXT_DB. Ignores failures.
+    static void sq_TXT_DB_delete(TXT_DB *db, const char **row);
+    /// Remove the row on position idx from TXT_DB. Ignores failures.
+    static void sq_TXT_DB_delete_row(TXT_DB *db, int idx);
+
     /// Callback hash function for serials. Used to create TXT_DB index of serials.
     static unsigned long index_serial_hash(const char **a);
     /// Callback compare function for serials. Used to create TXT_DB index of serials.
diff -u -r -N squid-3.3.0.1/src/StoreStats.cc squid-3.3.0.2/src/StoreStats.cc
--- squid-3.3.0.1/src/StoreStats.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/StoreStats.cc	2012-12-02 21:30:11.000000000 +1300
@@ -11,7 +11,7 @@
 
 StoreInfoStats::StoreInfoStats()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
 StoreInfoStats &
@@ -52,6 +52,6 @@
 
 StoreIoStats::StoreIoStats()
 {
-    xmemset(this, 0, sizeof(*this));
+    memset(this, 0, sizeof(*this));
 }
 
diff -u -r -N squid-3.3.0.1/src/tests/stub_tools.cc squid-3.3.0.2/src/tests/stub_tools.cc
--- squid-3.3.0.1/src/tests/stub_tools.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/tests/stub_tools.cc	2012-12-02 21:30:11.000000000 +1300
@@ -66,10 +66,3 @@
 void strwordquote(MemBuf * mb, const char *str) STUB
 void keepCapabilities(void) STUB
 void restoreCapabilities(int keep) STUB
-
-void*
-xmemset(void* dst, int val, size_t sz)
-{
-    assert(dst);
-    return memset(dst, val, sz);
-}
diff -u -r -N squid-3.3.0.1/src/tools.cc squid-3.3.0.2/src/tools.cc
--- squid-3.3.0.1/src/tools.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/tools.cc	2012-12-02 21:30:11.000000000 +1300
@@ -663,10 +663,10 @@
 void
 enter_suid(void)
 {
-    debugs(21, 3, "enter_suid: PID " << getpid() << " taking root priveleges");
+    debugs(21, 3, "enter_suid: PID " << getpid() << " taking root privileges");
 #if HAVE_SETRESUID
-
-    setresuid((uid_t)-1, 0, (uid_t)-1);
+    if (setresuid((uid_t)-1, 0, (uid_t)-1) < 0)
+        debugs (21, 3, "enter_suid: setresuid failed: " << xstrerror ());
 #else
 
     setuid(0);
@@ -691,10 +691,11 @@
     uid = geteuid();
     debugs(21, 3, "no_suid: PID " << getpid() << " giving up root priveleges forever");
 
-    setuid(0);
+    if (setuid(0) < 0)
+        debugs(50, DBG_IMPORTANT, "WARNING: no_suid: setuid(0): " << xstrerror());
 
     if (setuid(uid) < 0)
-        debugs(50, DBG_IMPORTANT, "no_suid: setuid: " << xstrerror());
+        debugs(50, DBG_IMPORTANT, "ERROR: no_suid: setuid(" << uid << "): " << xstrerror());
 
     restoreCapabilities(0);
 
@@ -1134,8 +1135,9 @@
             /* For IPV6 addresses also check for a colon */
             if (Config.appendDomain && !strchr(lt, '.') && !strchr(lt, ':')) {
                 /* I know it's ugly, but it's only at reconfig */
-                strncpy(buf2, lt, 512);
-                strncat(buf2, Config.appendDomain, 512 - strlen(lt) - 1);
+                strncpy(buf2, lt, sizeof(buf2)-1);
+                strncat(buf2, Config.appendDomain, sizeof(buf2) - strlen(lt) - 1);
+                buf2[sizeof(buf2)-1] = '\0';
                 host = buf2;
             } else {
                 host = lt;
@@ -1291,13 +1293,3 @@
     Ip::Interceptor.StopTransparency("Missing needed capability support.");
 #endif /* HAVE_SYS_CAPABILITY_H */
 }
-
-void *
-xmemset(void *dst, int val, size_t sz)
-{
-    // do debugs output
-    debugs(63, 9, "memset: dst=" << dst << ", val=" << val << ", bytes=" << sz);
-
-    // call the system one to do the actual work ~safely.
-    return memset(dst, val, sz);
-}
diff -u -r -N squid-3.3.0.1/src/tools.h squid-3.3.0.2/src/tools.h
--- squid-3.3.0.1/src/tools.h	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/tools.h	2012-12-02 21:30:11.000000000 +1300
@@ -91,7 +91,6 @@
 String ProcessRoles();
 
 void debug_trap(const char *);
-void *xmemset(void *dst, int, size_t);
 
 void logsFlush(void);
 
diff -u -r -N squid-3.3.0.1/src/tunnel.cc squid-3.3.0.2/src/tunnel.cc
--- squid-3.3.0.1/src/tunnel.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/tunnel.cc	2012-12-02 21:30:11.000000000 +1300
@@ -327,6 +327,14 @@
         commSetConnTimeout(from.conn, Config.Timeout.read, timeoutCall);
     }
 
+    /* Bump the dest connection read timeout on any activity */
+    /* see Bug 3659: tunnels can be weird, with very long one-way transfers */
+    if (Comm::IsConnOpen(to.conn)) {
+        AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "tunnelTimeout",
+                                         CommTimeoutCbPtrFun(tunnelTimeout, this));
+        commSetConnTimeout(to.conn, Config.Timeout.read, timeoutCall);
+    }
+
     if (errcode)
         from.error (xerrno);
     else if (len == 0 || !Comm::IsConnOpen(to.conn)) {
diff -u -r -N squid-3.3.0.1/src/unlinkd_daemon.cc squid-3.3.0.2/src/unlinkd_daemon.cc
--- squid-3.3.0.1/src/unlinkd_daemon.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/unlinkd_daemon.cc	2012-12-02 21:30:11.000000000 +1300
@@ -77,9 +77,11 @@
     setbuf(stdin, NULL);
     setbuf(stdout, NULL);
     close(2);
-    open(_PATH_DEVNULL, O_RDWR);
+    if (open(_PATH_DEVNULL, O_RDWR) < 0) {
+        ; // the irony of having to close(2) earlier is that we cannot report this failure.
+    }
 
-    while (fgets(buf, UNLINK_BUF_LEN, stdin)) {
+    while (fgets(buf, sizeof(buf), stdin)) {
         if ((t = strchr(buf, '\n')))
             *t = '\0';
         x = unlink(buf);
diff -u -r -N squid-3.3.0.1/src/url.cc squid-3.3.0.2/src/url.cc
--- squid-3.3.0.1/src/url.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/url.cc	2012-12-02 21:30:11.000000000 +1300
@@ -313,10 +313,12 @@
         /* Is there any login information? (we should eventually parse it above) */
         t = strrchr(host, '@');
         if (t != NULL) {
-            strcpy((char *) login, (char *) host);
+            strncpy((char *) login, (char *) host, sizeof(login)-1);
+            login[sizeof(login)-1] = '\0';
             t = strrchr(login, '@');
             *t = 0;
-            strcpy((char *) host, t + 1);
+            strncpy((char *) host, t + 1, sizeof(host)-1);
+            host[sizeof(host)-1] = '\0';
         }
 
         /* Is there any host information? (we should eventually parse it above) */
diff -u -r -N squid-3.3.0.1/src/wccp2.cc squid-3.3.0.2/src/wccp2.cc
--- squid-3.3.0.1/src/wccp2.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/src/wccp2.cc	2012-12-02 21:30:11.000000000 +1300
@@ -605,7 +605,7 @@
 
     SquidMD5Init(&M);
 
-    SquidMD5Update(&M, pwd, 8);
+    SquidMD5Update(&M, pwd, sizeof(pwd));
 
     SquidMD5Update(&M, packet, len);
 
@@ -650,7 +650,6 @@
 
     /* The password field, for the MD5 hash, needs to be 8 bytes and NUL padded. */
     memset(pwd, 0, sizeof(pwd));
-
     strncpy(pwd, srv->wccp_password, sizeof(pwd));
 
     /* Take a copy of the challenge: we need to NUL it before comparing */
@@ -660,7 +659,7 @@
 
     SquidMD5Init(&M);
 
-    SquidMD5Update(&M, pwd, 8);
+    SquidMD5Update(&M, pwd, sizeof(pwd));
 
     SquidMD5Update(&M, packet, len);
 
diff -u -r -N squid-3.3.0.1/test-suite/stub_tools.cc squid-3.3.0.2/test-suite/stub_tools.cc
--- squid-3.3.0.1/test-suite/stub_tools.cc	2012-10-21 01:02:24.000000000 +1300
+++ squid-3.3.0.2/test-suite/stub_tools.cc	2012-12-02 21:48:11.000000000 +1300
@@ -66,10 +66,3 @@
 void strwordquote(MemBuf * mb, const char *str) STUB
 void keepCapabilities(void) STUB
 void restoreCapabilities(int keep) STUB
-
-void*
-xmemset(void* dst, int val, size_t sz)
-{
-    assert(dst);
-    return memset(dst, val, sz);
-}
diff -u -r -N squid-3.3.0.1/tools/cachemgr.cc squid-3.3.0.2/tools/cachemgr.cc
--- squid-3.3.0.1/tools/cachemgr.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/tools/cachemgr.cc	2012-12-02 21:30:11.000000000 +1300
@@ -594,12 +594,15 @@
     if ((p = strchr(x, '\n')))
         *p = '\0';
     action = xstrtok(&x, '\t');
+    if (!action) {
+        xfree(buf);
+        return "";
+    }
     description = xstrtok(&x, '\t');
     if (!description)
         description = action;
-    if (!action)
-        return "";
     snprintf(html, sizeof(html), " <a href=\"%s\">%s</a>", menu_url(req, action), description);
+    xfree(buf);
     return html;
 }
 
@@ -828,7 +831,7 @@
     }
 
     if (!check_target_acl(req->hostname, req->port)) {
-        snprintf(buf, 1024, "target %s:%d not allowed in cachemgr.conf\n", req->hostname, req->port);
+        snprintf(buf, sizeof(buf), "target %s:%d not allowed in cachemgr.conf\n", req->hostname, req->port);
         error_html(buf);
         return 1;
     }
@@ -840,7 +843,7 @@
     } else if ((S = req->hostname))
         (void) 0;
     else {
-        snprintf(buf, 1024, "Unknown host: %s\n", req->hostname);
+        snprintf(buf, sizeof(buf), "Unknown host: %s\n", req->hostname);
         error_html(buf);
         return 1;
     }
@@ -854,17 +857,19 @@
 #else
     if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
 #endif
-        snprintf(buf, 1024, "socket: %s\n", xstrerror());
+        snprintf(buf, sizeof(buf), "socket: %s\n", xstrerror());
         error_html(buf);
+        S.FreeAddrInfo(AI);
         return 1;
     }
 
     if (connect(s, AI->ai_addr, AI->ai_addrlen) < 0) {
-        snprintf(buf, 1024, "connect %s: %s\n",
+        snprintf(buf, sizeof(buf), "connect %s: %s\n",
                  S.ToURL(ipbuf,MAX_IPSTRLEN),
                  xstrerror());
         error_html(buf);
         S.FreeAddrInfo(AI);
+        close(s);
         return 1;
     }
 
@@ -952,8 +957,6 @@
 read_post_request(void)
 {
     char *s;
-    char *buf;
-    int len;
 
     if ((s = getenv("REQUEST_METHOD")) == NULL)
         return NULL;
@@ -964,15 +967,34 @@
     if ((s = getenv("CONTENT_LENGTH")) == NULL)
         return NULL;
 
-    if ((len = atoi(s)) <= 0)
+    if (*s == '-') // negative length content huh?
+        return NULL;
+
+    uint64_t len;
+
+    char *endptr = s+ strlen(s);
+    if ((len = strtoll(s, &endptr, 10)) <= 0)
         return NULL;
 
-    buf = (char *)xmalloc(len + 1);
+    // limit the input to something reasonable.
+    // 4KB should be enough for the GET/POST data length, but may be extended.
+    size_t bufLen = (len >= 4096 ? len : 4095);
+    char *buf = (char *)xmalloc(bufLen + 1);
 
-    if (fread(buf, len, 1, stdin) == 0)
+    size_t readLen = fread(buf, bufLen, 1, stdin);
+    if (readLen == 0) {
+        xfree(buf);
         return NULL;
+    }
+    buf[readLen] = '\0';
+    len -= readLen;
 
-    buf[len] = '\0';
+    // purge the remainder of the request entity
+    while (len > 0) {
+        char temp[65535];
+        readLen = fread(temp, 65535, 1, stdin);
+        len -= readLen;
+    }
 
     return buf;
 }
@@ -1118,37 +1140,49 @@
     debug("cmgr: length ok\n");
 
     /* parse ( a lot of memory leaks, but that is cachemgr style :) */
-    if ((host_name = strtok(buf, "|")) == NULL)
+    if ((host_name = strtok(buf, "|")) == NULL) {
+        xfree(buf);
         return;
+    }
 
     debug("cmgr: decoded host: '%s'\n", host_name);
 
-    if ((time_str = strtok(NULL, "|")) == NULL)
+    if ((time_str = strtok(NULL, "|")) == NULL) {
+        xfree(buf);
         return;
+    }
 
     debug("cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now);
 
-    if ((user_name = strtok(NULL, "|")) == NULL)
+    if ((user_name = strtok(NULL, "|")) == NULL) {
+        xfree(buf);
         return;
+    }
 
     debug("cmgr: decoded uname: '%s'\n", user_name);
 
-    if ((passwd = strtok(NULL, "|")) == NULL)
+    if ((passwd = strtok(NULL, "|")) == NULL) {
+        xfree(buf);
         return;
+    }
 
     debug("cmgr: decoded passwd: '%s'\n", passwd);
 
     /* verify freshness and validity */
-    if (atoi(time_str) + passwd_ttl < now)
+    if (atoi(time_str) + passwd_ttl < now) {
+        xfree(buf);
         return;
+    }
 
-    if (strcasecmp(host_name, req->hostname))
+    if (strcasecmp(host_name, req->hostname)) {
+        xfree(buf);
         return;
+    }
 
     debug("cmgr: verified auth. info.\n");
 
     /* ok, accept */
-    xfree(req->user_name);
+    safe_free(req->user_name);
 
     req->user_name = xstrdup(user_name);
 
@@ -1190,6 +1224,7 @@
 
     snprintf(&buf[stringLength], sizeof(buf) - stringLength, "Proxy-Authorization: Basic %s\r\n", str64);
 
+    xfree(str64);
     return buf;
 }
 
diff -u -r -N squid-3.3.0.1/tools/purge/conffile.cc squid-3.3.0.2/tools/purge/conffile.cc
--- squid-3.3.0.1/tools/purge/conffile.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/tools/purge/conffile.cc	2012-12-02 21:30:11.000000000 +1300
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <fstream>
 
 int
 readConfigFile( CacheDirVector& cachedir, const char* fn, FILE* debug )
@@ -58,8 +59,8 @@
 
     // try to open file
     if ( debug ) fprintf( debug, "# trying to open %s\n", fn ? fn : "(null)" );
-    FILE* in = fopen( fn, "r" );
-    if ( in == NULL ) {
+    std::ifstream cfgin(fn);
+    if (!cfgin) {
         fprintf( stderr, "fopen %s: %s\n", fn, strerror(errno) );
         return -1;
     }
@@ -81,7 +82,7 @@
     regmatch_t subs[8];
     char *s, line[1024];
     CacheDir cd;
-    while ( fgets( line, sizeof(line), in ) ) {
+    while ( cfgin.getline( line, sizeof(line)) ) {
         // FIXME: overly long lines
 
         // terminate line at start of comment
@@ -99,7 +100,7 @@
                 fprintf( stderr, "while matching \"%s\" against %s%s\n",
                          expression, line, buffer );
                 regfree(&rexp);
-                fclose(in);
+                cfgin.close();
                 return -1;
             }
         } else {
@@ -176,7 +177,7 @@
         }
     }
 
-    fclose(in);
+    cfgin.close();
     regfree(&rexp);
     return cachedir.size();
 }
diff -u -r -N squid-3.3.0.1/tools/purge/purge.cc squid-3.3.0.2/tools/purge/purge.cc
--- squid-3.3.0.1/tools/purge/purge.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/tools/purge/purge.cc	2012-12-02 21:30:11.000000000 +1300
@@ -489,7 +489,8 @@
     if ( ::iamalive ) {
         static char alivelist[4][3] = { "\\\b", "|\b", "/\b", "-\b" };
         static unsigned short alivecount = 0;
-        assert( write( STDOUT_FILENO, alivelist[alivecount++ & 3], 2 ) == 2 );
+        const int write_success = write(STDOUT_FILENO, alivelist[alivecount++ & 3], 2);
+        assert(write_success == 2);
     }
 
     bool flag = true;
@@ -627,13 +628,15 @@
         case 'C':
             if ( optarg && *optarg ) {
                 if ( copydir ) xfree( (void*) copydir );
-                assert( (copydir = xstrdup(optarg)) );
+                copydir = xstrdup(optarg);
+                assert(copydir);
             }
             break;
         case 'c':
             if ( optarg && *optarg ) {
-                if ( *conffile ) xfree((void*) conffile );
-                assert( (conffile = xstrdup(optarg)) );
+                if ( *conffile ) xfree((void*) conffile);
+                conffile = xstrdup(optarg);
+                assert(conffile);
             }
             break;
 
diff -u -r -N squid-3.3.0.1/tools/squidclient.cc squid-3.3.0.2/tools/squidclient.cc
--- squid-3.3.0.1/tools/squidclient.cc	2012-10-21 00:32:26.000000000 +1300
+++ squid-3.3.0.2/tools/squidclient.cc	2012-12-02 21:30:11.000000000 +1300
@@ -265,13 +265,11 @@
                 break;
 
             case 'A':
-                if (optarg != NULL)
-                    useragent = optarg;
+                useragent = optarg;
                 break;
 
             case 'h':		/* remote host */
-                if (optarg != NULL)
-                    hostname = optarg;
+                hostname = optarg;
                 break;
 
             case 'j':
@@ -279,13 +277,11 @@
                 break;
 
             case 'V':
-                if (optarg != NULL)
-                    version = optarg;
+                version = optarg;
                 break;
 
             case 'l':		/* local host */
-                if (optarg != NULL)
-                    localhost = optarg;
+                localhost = optarg;
                 break;
 
             case 's':		/* silent */
@@ -418,7 +414,9 @@
         setmode(put_fd, O_BINARY);
 #endif
 
-        fstat(put_fd, &sb);
+        if (fstat(put_fd, &sb) < 0) {
+            fprintf(stderr, "%s: can't identify length of file (%s)\n", argv[0], xstrerror());
+        }
     }
 
     if (!host) {
