diff -u -r -N squid-4.7/ChangeLog squid-4.8/ChangeLog
--- squid-4.7/ChangeLog	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/ChangeLog	2019-07-10 07:05:20.000000000 +1200
@@ -1,3 +1,22 @@
+Changes to squid-4.8 (09 Jul 2019):
+
+	- Bug 4957: Multiple XSS issues in cachemgr.cgi
+	- Bug 4953: to_localhost does not include ::
+	- Bug 4937: cachemgr.cgi: unallocated memory access
+	- Bug 4936: terminating c-strings beyond BASE64_DECODE_LENGTH
+	- Bug 4889: Ignore ECONNABORTED in accept(2)
+	- Bug 4842: Memory leak when http_reply_access uses external_acl
+	- TLS: Fix tls-min-version= being ignored
+	- TLS: Add the NO_TLSv1_3 option to available tls-options values
+	- HTTP: RFC 7230 forbids generation of userinfo subcomponent of https URL
+	- HTTP: Remove userinfo support from old protocols
+	- HTTP: Fix Digest auth parameter parsing
+	- HTTP: Send Connection:close with the known-last request on a connection
+	- HTTP: Fix handling of tiny invalid responses
+	- Replace uudecode with libnettle base64 decoder
+	- Update HttpHeader::getAuth to SBuf
+	- ... and some compile issues
+
 Changes to squid-4.7 (06 May 2019):
 
 	- Bug 4942: --with-filedescriptors does not do anything
diff -u -r -N squid-4.7/compat/os/mswindows.h squid-4.8/compat/os/mswindows.h
--- squid-4.7/compat/os/mswindows.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/compat/os/mswindows.h	2019-07-10 07:05:20.000000000 +1200
@@ -358,6 +358,9 @@
 #ifndef ENOTSUP
 #define ENOTSUP WSAEOPNOTSUPP
 #endif
+#ifndef ECONNABORTED
+#define ECONNABORTED WSAECONNABORTED
+#endif
 
 #undef h_errno
 #define h_errno errno /* we'll set it ourselves */
diff -u -r -N squid-4.7/configure squid-4.8/configure
--- squid-4.7/configure	2019-05-07 01:56:57.000000000 +1200
+++ squid-4.8/configure	2019-07-10 07:16:52.000000000 +1200
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.7.
+# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.8.
 #
 # Report bugs to <http://bugs.squid-cache.org/>.
 #
@@ -595,8 +595,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='4.7'
-PACKAGE_STRING='Squid Web Proxy 4.7'
+PACKAGE_VERSION='4.8'
+PACKAGE_STRING='Squid Web Proxy 4.8'
 PACKAGE_BUGREPORT='http://bugs.squid-cache.org/'
 PACKAGE_URL=''
 
@@ -1651,7 +1651,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 4.7 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 4.8 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1722,7 +1722,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 4.7:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 4.8:";;
    esac
   cat <<\_ACEOF
 
@@ -2155,7 +2155,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 4.7
+Squid Web Proxy configure 4.8
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -3259,7 +3259,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 4.7, which was
+It was created by Squid Web Proxy $as_me 4.8, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4126,7 +4126,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='4.7'
+ VERSION='4.8'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -44215,7 +44215,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 4.7, which was
+This file was extended by Squid Web Proxy $as_me 4.8, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -44281,7 +44281,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 4.7
+Squid Web Proxy config.status 4.8
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -u -r -N squid-4.7/configure.ac squid-4.8/configure.ac
--- squid-4.7/configure.ac	2019-05-07 01:56:57.000000000 +1200
+++ squid-4.8/configure.ac	2019-07-10 07:16:52.000000000 +1200
@@ -5,7 +5,7 @@
 ## Please see the COPYING and CONTRIBUTORS files for details.
 ##
 
-AC_INIT([Squid Web Proxy],[4.7],[http://bugs.squid-cache.org/],[squid])
+AC_INIT([Squid Web Proxy],[4.8],[http://bugs.squid-cache.org/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
diff -u -r -N squid-4.7/doc/release-notes/release-4.html squid-4.8/doc/release-notes/release-4.html
--- squid-4.7/doc/release-notes/release-4.html	2019-05-07 02:07:31.000000000 +1200
+++ squid-4.8/doc/release-notes/release-4.html	2019-07-10 07:25:09.000000000 +1200
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.73">
- <TITLE>Squid 4.7 release notes</TITLE>
+ <TITLE>Squid 4.8 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 4.7 release notes</H1>
+<H1>Squid 4.8 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -63,7 +63,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-4.7 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-4.8 for testing.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v4/">http://www.squid-cache.org/Versions/v4/</A> or the
 <A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
@@ -384,6 +384,7 @@
 <P>New <EM>--consensus</EM>, <EM>--client-requested</EM> and
 <EM>--server-provided</EM> flags for the <EM>ssl::server_name</EM>
 type to control which server name to match against.</P>
+<P>Added <EM>::/128</EM> IPv6 range to <EM>to_localhost</EM> ACL.</P>
 
 <DT><B>auth_param</B><DD>
 <P>New parameter <EM>queue-size=</EM> to set the maximum number
@@ -399,6 +400,7 @@
 <P>New option <EM>tls-min-version=1.N</EM> to set minimum TLS version allowed.</P>
 <P>New option <EM>tls-default-ca</EM> replaces <EM>sslflags=NO_DEFAULT_CA</EM></P>
 <P>New option <EM>tls-no-npn</EM> to disable sending TLS NPN extension.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>All <EM>ssloptions=</EM> values for SSLv2 configuration or disabling
 have been removed.</P>
 <P>Removed <EM>sslversion=</EM> option. Use <EM>tls-options=</EM> instead.</P>
@@ -432,6 +434,7 @@
 <P>New option <EM>tls-default-ca</EM> replaces <EM>sslflags=NO_DEFAULT_CA</EM>,
 the default is also changed to OFF.</P>
 <P>New option <EM>tls-no-npn</EM> to disable sending TLS NPN extension.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>All <EM>option=</EM> values for SSLv2 configuration or disabling
 have been removed.</P>
 <P>Removed <EM>version=</EM> option. Use <EM>tls-options=</EM> instead.</P>
@@ -444,6 +447,7 @@
 <P>New option <EM>tls-default-ca</EM> replaces <EM>sslflags=NO_DEFAULT_CA</EM>,
 the default is also changed to OFF.</P>
 <P>New option <EM>tls-no-npn</EM> to disable sending TLS NPN extension.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>All <EM>options=</EM> values for SSLv2
 configuration or disabling have been removed.</P>
 <P>Removed <EM>version=</EM> option. Use <EM>tls-options=</EM> instead.</P>
@@ -462,6 +466,7 @@
 <P>New <EM>tls-min-version=1.N</EM> option to set minimum TLS version allowed
 on server connections.</P>
 <P>New <EM>tls-options=</EM> option to set OpenSSL library parameters.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>New <EM>tls-flags=</EM> option to set flags modifying Squid TLS operations.</P>
 <P>New <EM>tls-cipher=</EM> option to set a list of ciphers permitted.</P>
 <P>New <EM>tls-cafile=</EM> option to set a file with additional CA
diff -u -r -N squid-4.7/include/uudecode.h squid-4.8/include/uudecode.h
--- squid-4.7/include/uudecode.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/include/uudecode.h	1970-01-01 12:00:00.000000000 +1200
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#ifndef _SQUID_UUDECODE_H
-#define _SQUID_UUDECODE_H
-
-#ifdef __cplusplus
-extern "C"
-#else
-extern
-#endif
-
-char *uudecode(const char *);
-
-#endif /* _SQUID_UUDECODE_H */
-
diff -u -r -N squid-4.7/include/version.h squid-4.8/include/version.h
--- squid-4.7/include/version.h	2019-05-07 01:56:57.000000000 +1200
+++ squid-4.8/include/version.h	2019-07-10 07:16:52.000000000 +1200
@@ -7,7 +7,7 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1557151008
+#define SQUID_RELEASE_TIME 1562699800
 #endif
 
 /*
diff -u -r -N squid-4.7/lib/html_quote.c squid-4.8/lib/html_quote.c
--- squid-4.7/lib/html_quote.c	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/lib/html_quote.c	2019-07-10 07:05:20.000000000 +1200
@@ -90,7 +90,7 @@
         }
         if (escape) {
             /* Ok, An escaped form was found above. Use it */
-            strncpy(dst, escape, 6);
+            strncpy(dst, escape, 7);
             dst += strlen(escape);
         } else {
             /* Apparently there is no need to escape this character */
diff -u -r -N squid-4.7/lib/Makefile.am squid-4.8/lib/Makefile.am
--- squid-4.7/lib/Makefile.am	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/lib/Makefile.am	2019-07-10 07:05:20.000000000 +1200
@@ -61,8 +61,7 @@
 	html_quote.c \
 	md5.c \
 	rfc1738.c \
-	rfc2617.c \
-	uudecode.c
+	rfc2617.c
 
 libmisccontainers_la_SOURCES = \
 	hash.cc
diff -u -r -N squid-4.7/lib/Makefile.in squid-4.8/lib/Makefile.in
--- squid-4.7/lib/Makefile.in	2019-05-07 01:56:53.000000000 +1200
+++ squid-4.8/lib/Makefile.in	2019-07-10 07:16:46.000000000 +1200
@@ -185,7 +185,7 @@
 am__v_lt_1 = 
 libmiscencoding_la_LIBADD =
 am_libmiscencoding_la_OBJECTS = base64.lo charset.lo html_quote.lo \
-	md5.lo rfc1738.lo rfc2617.lo uudecode.lo
+	md5.lo rfc1738.lo rfc2617.lo
 libmiscencoding_la_OBJECTS = $(am_libmiscencoding_la_OBJECTS)
 libmiscutil_la_LIBADD =
 am_libmiscutil_la_OBJECTS = getfullhostname.lo heap.lo iso3307.lo \
@@ -236,8 +236,8 @@
 	./$(DEPDIR)/radix.Plo ./$(DEPDIR)/rfc1123.Plo \
 	./$(DEPDIR)/rfc1738.Plo ./$(DEPDIR)/rfc2617.Plo \
 	./$(DEPDIR)/sspwin32.Plo ./$(DEPDIR)/stub_memaccount.Plo \
-	./$(DEPDIR)/util.Plo ./$(DEPDIR)/uudecode.Plo \
-	./$(DEPDIR)/xusleep.Plo tests/$(DEPDIR)/testRFC1738.Po
+	./$(DEPDIR)/util.Plo ./$(DEPDIR)/xusleep.Plo \
+	tests/$(DEPDIR)/testRFC1738.Po
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -838,8 +838,7 @@
 	html_quote.c \
 	md5.c \
 	rfc1738.c \
-	rfc2617.c \
-	uudecode.c
+	rfc2617.c
 
 libmisccontainers_la_SOURCES = \
 	hash.cc
@@ -972,7 +971,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sspwin32.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub_memaccount.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uudecode.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xusleep.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/testRFC1738.Po@am__quote@ # am--include-marker
 
@@ -1421,7 +1419,6 @@
 	-rm -f ./$(DEPDIR)/sspwin32.Plo
 	-rm -f ./$(DEPDIR)/stub_memaccount.Plo
 	-rm -f ./$(DEPDIR)/util.Plo
-	-rm -f ./$(DEPDIR)/uudecode.Plo
 	-rm -f ./$(DEPDIR)/xusleep.Plo
 	-rm -f tests/$(DEPDIR)/testRFC1738.Po
 	-rm -f Makefile
@@ -1488,7 +1485,6 @@
 	-rm -f ./$(DEPDIR)/sspwin32.Plo
 	-rm -f ./$(DEPDIR)/stub_memaccount.Plo
 	-rm -f ./$(DEPDIR)/util.Plo
-	-rm -f ./$(DEPDIR)/uudecode.Plo
 	-rm -f ./$(DEPDIR)/xusleep.Plo
 	-rm -f tests/$(DEPDIR)/testRFC1738.Po
 	-rm -f Makefile
diff -u -r -N squid-4.7/lib/uudecode.c squid-4.8/lib/uudecode.c
--- squid-4.7/lib/uudecode.c	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/lib/uudecode.c	1970-01-01 12:00:00.000000000 +1200
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 1996-2019 The Squid Software Foundation and contributors
- *
- * Squid software is distributed under GPLv2+ license and includes
- * contributions from numerous individuals and organizations.
- * Please see the COPYING and CONTRIBUTORS files for details.
- */
-
-#include "squid.h"
-#include "uudecode.h"
-
-/* aaaack but it's fast and const should make it shared text page. */
-const int pr2six[256] = {
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
-    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
-    10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27,
-    28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
-};
-
-char *
-uudecode(const char *bufcoded)
-{
-    int nbytesdecoded;
-    const unsigned char *bufin;
-    char *bufplain;
-    unsigned char *bufout;
-    int nprbytes;
-
-    /* Strip leading whitespace. */
-
-    while (*bufcoded == ' ' || *bufcoded == '\t')
-        bufcoded++;
-
-    /* Figure out how many characters are in the input buffer.
-     * Allocate this many from the per-transaction pool for the result.
-     */
-    bufin = (const unsigned char *) bufcoded;
-    while (pr2six[*(bufin++)] <= 63);
-    nprbytes = (const char *) bufin - bufcoded - 1;
-    nbytesdecoded = ((nprbytes + 3) / 4) * 3;
-
-    bufplain = xmalloc(nbytesdecoded + 1);
-    bufout = (unsigned char *) bufplain;
-    bufin = (const unsigned char *) bufcoded;
-
-    while (nprbytes > 0) {
-        *(bufout++) =
-            (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
-        *(bufout++) =
-            (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
-        *(bufout++) =
-            (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
-        bufin += 4;
-        nprbytes -= 4;
-    }
-
-    if (nprbytes & 03) {
-        if (pr2six[bufin[-2]] > 63)
-            nbytesdecoded -= 2;
-        else
-            nbytesdecoded -= 1;
-    }
-    bufplain[nbytesdecoded] = '\0';
-    return bufplain;
-}
-
diff -u -r -N squid-4.7/RELEASENOTES.html squid-4.8/RELEASENOTES.html
--- squid-4.7/RELEASENOTES.html	2019-05-07 02:07:31.000000000 +1200
+++ squid-4.8/RELEASENOTES.html	2019-07-10 07:25:09.000000000 +1200
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.73">
- <TITLE>Squid 4.7 release notes</TITLE>
+ <TITLE>Squid 4.8 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 4.7 release notes</H1>
+<H1>Squid 4.8 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -63,7 +63,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-4.7 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-4.8 for testing.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v4/">http://www.squid-cache.org/Versions/v4/</A> or the
 <A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
@@ -384,6 +384,7 @@
 <P>New <EM>--consensus</EM>, <EM>--client-requested</EM> and
 <EM>--server-provided</EM> flags for the <EM>ssl::server_name</EM>
 type to control which server name to match against.</P>
+<P>Added <EM>::/128</EM> IPv6 range to <EM>to_localhost</EM> ACL.</P>
 
 <DT><B>auth_param</B><DD>
 <P>New parameter <EM>queue-size=</EM> to set the maximum number
@@ -399,6 +400,7 @@
 <P>New option <EM>tls-min-version=1.N</EM> to set minimum TLS version allowed.</P>
 <P>New option <EM>tls-default-ca</EM> replaces <EM>sslflags=NO_DEFAULT_CA</EM></P>
 <P>New option <EM>tls-no-npn</EM> to disable sending TLS NPN extension.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>All <EM>ssloptions=</EM> values for SSLv2 configuration or disabling
 have been removed.</P>
 <P>Removed <EM>sslversion=</EM> option. Use <EM>tls-options=</EM> instead.</P>
@@ -432,6 +434,7 @@
 <P>New option <EM>tls-default-ca</EM> replaces <EM>sslflags=NO_DEFAULT_CA</EM>,
 the default is also changed to OFF.</P>
 <P>New option <EM>tls-no-npn</EM> to disable sending TLS NPN extension.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>All <EM>option=</EM> values for SSLv2 configuration or disabling
 have been removed.</P>
 <P>Removed <EM>version=</EM> option. Use <EM>tls-options=</EM> instead.</P>
@@ -444,6 +447,7 @@
 <P>New option <EM>tls-default-ca</EM> replaces <EM>sslflags=NO_DEFAULT_CA</EM>,
 the default is also changed to OFF.</P>
 <P>New option <EM>tls-no-npn</EM> to disable sending TLS NPN extension.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>All <EM>options=</EM> values for SSLv2
 configuration or disabling have been removed.</P>
 <P>Removed <EM>version=</EM> option. Use <EM>tls-options=</EM> instead.</P>
@@ -462,6 +466,7 @@
 <P>New <EM>tls-min-version=1.N</EM> option to set minimum TLS version allowed
 on server connections.</P>
 <P>New <EM>tls-options=</EM> option to set OpenSSL library parameters.</P>
+<P>New <EM>tls-options=</EM> option value to disable TLS/1.3.</P>
 <P>New <EM>tls-flags=</EM> option to set flags modifying Squid TLS operations.</P>
 <P>New <EM>tls-cipher=</EM> option to set a list of ciphers permitted.</P>
 <P>New <EM>tls-cafile=</EM> option to set a file with additional CA
diff -u -r -N squid-4.7/src/acl/external/delayer/ext_delayer_acl.8 squid-4.8/src/acl/external/delayer/ext_delayer_acl.8
--- squid-4.7/src/acl/external/delayer/ext_delayer_acl.8	2019-05-07 02:07:33.000000000 +1200
+++ squid-4.8/src/acl/external/delayer/ext_delayer_acl.8	2019-07-10 07:25:12.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_DELAYER_ACL 8"
-.TH EXT_DELAYER_ACL 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH EXT_DELAYER_ACL 8 "2019-07-09" "perl v5.28.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-4.7/src/acl/external/SQL_session/ext_sql_session_acl.8 squid-4.8/src/acl/external/SQL_session/ext_sql_session_acl.8
--- squid-4.7/src/acl/external/SQL_session/ext_sql_session_acl.8	2019-05-07 02:07:34.000000000 +1200
+++ squid-4.8/src/acl/external/SQL_session/ext_sql_session_acl.8	2019-07-10 07:25:12.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_SQL_SESSION_ACL 8"
-.TH EXT_SQL_SESSION_ACL 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH EXT_SQL_SESSION_ACL 8 "2019-07-09" "perl v5.28.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-4.7/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 squid-4.8/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-4.7/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8	2019-05-07 02:07:34.000000000 +1200
+++ squid-4.8/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8	2019-07-10 07:25:12.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_WBINFO_GROUP_ACL 8"
-.TH EXT_WBINFO_GROUP_ACL 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL 8 "2019-07-09" "perl v5.28.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-4.7/src/anyp/Uri.cc squid-4.8/src/anyp/Uri.cc
--- squid-4.7/src/anyp/Uri.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/anyp/Uri.cc	2019-07-10 07:05:20.000000000 +1200
@@ -495,10 +495,10 @@
         absolute_.append(":",1);
         if (getScheme() != AnyP::PROTO_URN) {
             absolute_.append("//", 2);
-            const bool omitUserInfo = getScheme() == AnyP::PROTO_HTTP ||
-                                      getScheme() != AnyP::PROTO_HTTPS ||
-                                      userInfo().isEmpty();
-            if (!omitUserInfo) {
+            const bool allowUserInfo = getScheme() == AnyP::PROTO_FTP ||
+                                       getScheme() == AnyP::PROTO_UNKNOWN;
+
+            if (allowUserInfo && !userInfo().isEmpty()) {
                 absolute_.append(userInfo());
                 absolute_.append("@", 1);
             }
diff -u -r -N squid-4.7/src/auth/basic/Config.cc squid-4.8/src/auth/basic/Config.cc
--- squid-4.7/src/auth/basic/Config.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/auth/basic/Config.cc	2019-07-10 07:05:20.000000000 +1200
@@ -20,6 +20,7 @@
 #include "auth/CredentialsCache.h"
 #include "auth/Gadgets.h"
 #include "auth/State.h"
+#include "base64.h"
 #include "cache_cf.h"
 #include "charset.h"
 #include "helper.h"
@@ -30,7 +31,6 @@
 #include "SquidTime.h"
 #include "Store.h"
 #include "util.h"
-#include "uudecode.h"
 #include "wordlist.h"
 
 /* Basic Scheme */
@@ -169,10 +169,17 @@
     // XXX: really? is the \n actually still there? does the header parse not drop it?
     char *eek = xstrdup(proxy_auth);
     strtok(eek, "\n");
-    char *cleartext = uudecode(eek);
-    safe_free(eek);
 
-    if (cleartext) {
+    const size_t srcLen = strlen(eek);
+    char *cleartext = static_cast<char*>(xmalloc(BASE64_DECODE_LENGTH(srcLen)+1));
+
+    struct base64_decode_ctx ctx;
+    base64_decode_init(&ctx);
+
+    size_t dstLen = 0;
+    if (base64_decode_update(&ctx, &dstLen, reinterpret_cast<uint8_t*>(cleartext), srcLen, eek) && base64_decode_final(&ctx)) {
+        cleartext[dstLen] = '\0';
+
         /*
          * Don't allow NL or CR in the credentials.
          * Oezguer Kesim <oec@codeblau.de>
@@ -183,7 +190,12 @@
             debugs(29, DBG_IMPORTANT, "WARNING: Bad characters in authorization header '" << httpAuthHeader << "'");
             safe_free(cleartext);
         }
+    } else {
+        debugs(29, 2, "WARNING: Invalid Base64 character in authorization header '" << httpAuthHeader << "'");
+        safe_free(cleartext);
     }
+
+    safe_free(eek);
     return cleartext;
 }
 
diff -u -r -N squid-4.7/src/auth/basic/DB/basic_db_auth.8 squid-4.8/src/auth/basic/DB/basic_db_auth.8
--- squid-4.7/src/auth/basic/DB/basic_db_auth.8	2019-05-07 02:07:34.000000000 +1200
+++ squid-4.8/src/auth/basic/DB/basic_db_auth.8	2019-07-10 07:25:13.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_DB_AUTH 8"
-.TH BASIC_DB_AUTH 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 8 "2019-07-09" "perl v5.28.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-4.7/src/auth/basic/POP3/basic_pop3_auth.8 squid-4.8/src/auth/basic/POP3/basic_pop3_auth.8
--- squid-4.7/src/auth/basic/POP3/basic_pop3_auth.8	2019-05-07 02:07:34.000000000 +1200
+++ squid-4.8/src/auth/basic/POP3/basic_pop3_auth.8	2019-07-10 07:25:13.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_POP3_AUTH 8"
-.TH BASIC_POP3_AUTH 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH BASIC_POP3_AUTH 8 "2019-07-09" "perl v5.28.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-4.7/src/auth/digest/Config.cc squid-4.8/src/auth/digest/Config.cc
--- squid-4.7/src/auth/digest/Config.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/auth/digest/Config.cc	2019-07-10 07:05:20.000000000 +1200
@@ -787,14 +787,14 @@
             if (keyName == SBuf("domain",6) || keyName == SBuf("uri",3)) {
                 // domain is Special. Not a quoted-string, must not be de-quoted. But is wrapped in '"'
                 // BUG 3077: uri= can also be sent to us in a mangled (invalid!) form like domain
-                if (*p == '"' && *(p + vlen -1) == '"') {
+                if (vlen > 1 && *p == '"' && *(p + vlen -1) == '"') {
                     value.limitInit(p+1, vlen-2);
                 }
             } else if (keyName == SBuf("qop",3)) {
                 // qop is more special.
                 // On request this must not be quoted-string de-quoted. But is several values wrapped in '"'
                 // On response this is a single un-quoted token.
-                if (*p == '"' && *(p + vlen -1) == '"') {
+                if (vlen > 1 && *p == '"' && *(p + vlen -1) == '"') {
                     value.limitInit(p+1, vlen-2);
                 } else {
                     value.limitInit(p, vlen);
diff -u -r -N squid-4.7/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc squid-4.8/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc
--- squid-4.7/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc	2019-07-10 07:05:20.000000000 +1200
@@ -822,7 +822,8 @@
                 goto cleanup;
             if (major_status & GSS_S_CONTINUE_NEEDED) {
                 debug((char *) "%s| %s: INFO: continuation needed\n", LogTime(), PROGRAM);
-                fprintf(stdout, "ERR token=%s\n", token);
+                // XXX: where to get the server token for delivery to client? token is nullptr here.
+                fprintf(stdout, "ERR\n");
                 goto cleanup;
             }
             gss_release_buffer(&minor_status, &output_token);
diff -u -r -N squid-4.7/src/auth/negotiate/wrapper/negotiate_wrapper.cc squid-4.8/src/auth/negotiate/wrapper/negotiate_wrapper.cc
--- squid-4.7/src/auth/negotiate/wrapper/negotiate_wrapper.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/auth/negotiate/wrapper/negotiate_wrapper.cc	2019-07-10 07:05:20.000000000 +1200
@@ -112,7 +112,7 @@
     char tbuff[MAX_AUTHTOKEN_LEN];
     char buff[MAX_AUTHTOKEN_LEN+2];
     char *c;
-    int length;
+    size_t length;
     uint8_t *token = NULL;
 
     while (1) {
@@ -136,7 +136,7 @@
             *c = '\0';
             length = c - buf;
             if (debug_enabled)
-                fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n",
+                fprintf(stderr, "%s| %s: Got '%s' from squid (length: %" PRIuSIZE ").\n",
                         LogTime(), PROGRAM, buf, length);
         } else {
             if (debug_enabled)
@@ -181,11 +181,11 @@
         }
         length = BASE64_DECODE_LENGTH(strlen(buf+3));
         if (debug_enabled)
-            fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n",
-                    LogTime(), PROGRAM, buf + 3, (int) length);
+            fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %" PRIuSIZE ").\n",
+                    LogTime(), PROGRAM, buf + 3, length);
 
         safe_free(token);
-        if (!(token = static_cast<uint8_t *>(xmalloc(length)))) {
+        if (!(token = static_cast<uint8_t *>(xmalloc(length+1)))) {
             fprintf(stderr, "%s| %s: Error allocating memory for token\n", LogTime(), PROGRAM);
             return 1;
         }
@@ -200,6 +200,7 @@
             fprintf(stdout, "BH Invalid negotiate request token\n");
             continue;
         }
+        assert(dstLen <= length);
         length = dstLen;
         token[dstLen] = '\0';
 
diff -u -r -N squid-4.7/src/cache_cf.cc squid-4.8/src/cache_cf.cc
--- squid-4.7/src/cache_cf.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/cache_cf.cc	2019-07-10 07:05:20.000000000 +1200
@@ -2302,6 +2302,9 @@
         peerDigestCreate(p);
 #endif
 
+    if (p->secure.encryptTransport)
+        p->secure.parseOptions();
+
     p->index =  ++Config.npeers;
 
     while (*head != NULL)
@@ -3772,6 +3775,7 @@
             self_destruct();
             return;
         }
+        s->secure.parseOptions();
     }
 
     // *_port line should now be fully valid so we can clone it if necessary
diff -u -r -N squid-4.7/src/cache_manager.cc squid-4.8/src/cache_manager.cc
--- squid-4.7/src/cache_manager.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/cache_manager.cc	2019-07-10 07:05:20.000000000 +1200
@@ -27,6 +27,7 @@
 #include "mgr/FunAction.h"
 #include "mgr/QueryParams.h"
 #include "protos.h"
+#include "sbuf/StringConvert.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
 #include "Store.h"
@@ -243,20 +244,20 @@
     // TODO: use the authentication system decode to retrieve these details properly.
 
     /* base 64 _decoded_ user:passwd pair */
-    const char *basic_cookie = request->header.getAuth(Http::HdrType::AUTHORIZATION, "Basic");
+    const auto basic_cookie(request->header.getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
 
-    if (!basic_cookie)
+    if (basic_cookie.isEmpty())
         return;
 
-    const char *passwd_del;
-    if (!(passwd_del = strchr(basic_cookie, ':'))) {
+    const auto colonPos = basic_cookie.find(':');
+    if (colonPos == SBuf::npos) {
         debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'");
         return;
     }
 
     /* found user:password pair, reset old values */
-    params.userName.limitInit(basic_cookie, passwd_del - basic_cookie);
-    params.password = passwd_del + 1;
+    params.userName = SBufToString(basic_cookie.substr(0, colonPos));
+    params.password = SBufToString(basic_cookie.substr(colonPos+1));
 
     /* warning: this prints decoded password which maybe not be what you want to do @?@ @?@ */
     debugs(16, 9, "CacheManager::ParseHeaders: got user: '" <<
diff -u -r -N squid-4.7/src/cf.data.pre squid-4.8/src/cf.data.pre
--- squid-4.7/src/cf.data.pre	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/cf.data.pre	2019-07-10 07:05:20.000000000 +1200
@@ -1003,7 +1003,7 @@
 DEFAULT: all src all
 DEFAULT: manager url_regex -i ^cache_object:// +i ^https?://[^/]+/squid-internal-mgr/
 DEFAULT: localhost src 127.0.0.1/32 ::1
-DEFAULT: to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
+DEFAULT: to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1/128 ::/128
 DEFAULT_DOC: ACLs all, manager, localhost, and to_localhost are predefined.
 DOC_START
 	Defining an Access List
@@ -2751,7 +2751,7 @@
 	min-version=1.N
 			The minimum TLS protocol version to permit.
 			To control SSLv3 use the options= parameter.
-			Supported Values: 1.0 (default), 1.1, 1.2
+			Supported Values: 1.0 (default), 1.1, 1.2, 1.3
 
 	options=...	Specify various TLS/SSL implementation options.
 
diff -u -r -N squid-4.7/src/clients/FtpGateway.cc squid-4.8/src/clients/FtpGateway.cc
--- squid-4.7/src/clients/FtpGateway.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/clients/FtpGateway.cc	2019-07-10 07:05:20.000000000 +1200
@@ -1039,7 +1039,7 @@
 
 #if HAVE_AUTH_MODULE_BASIC
     /* Check HTTP Authorization: headers (better than defaults, but less than URL) */
-    const SBuf auth(req_hdr->getAuth(Http::HdrType::AUTHORIZATION, "Basic"));
+    const auto auth(req_hdr->getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
     if (!auth.isEmpty()) {
         flags.authenticated = 1;
         loginParser(auth, false);
diff -u -r -N squid-4.7/src/client_side.cc squid-4.8/src/client_side.cc
--- squid-4.7/src/client_side.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/client_side.cc	2019-07-10 07:05:20.000000000 +1200
@@ -2522,9 +2522,10 @@
 
 /// Create TLS connection structure and update fd_table
 static bool
-httpsCreate(const Comm::ConnectionPointer &conn, const Security::ContextPointer &ctx)
+httpsCreate(const ConnStateData *connState, const Security::ContextPointer &ctx)
 {
-    if (Security::CreateServerSession(ctx, conn, "client https start")) {
+    const auto conn = connState->clientConnection;
+    if (Security::CreateServerSession(ctx, conn, connState->port->secure, "client https start")) {
         debugs(33, 5, "will negotiate TLS on " << conn);
         return true;
     }
@@ -2709,7 +2710,7 @@
     assert(connState);
     const Comm::ConnectionPointer &details = connState->clientConnection;
 
-    if (!ctx || !httpsCreate(details, ctx))
+    if (!ctx || !httpsCreate(connState, ctx))
         return;
 
     typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
@@ -3072,7 +3073,7 @@
         }
     }
 
-    if (!httpsCreate(clientConnection, ctx))
+    if (!httpsCreate(this, ctx))
         return;
 
     // bumped intercepted conns should already have Config.Timeout.request set
@@ -3293,7 +3294,7 @@
     Security::ContextPointer unConfiguredCTX(Ssl::createSSLContext(port->secure.signingCa.cert, port->secure.signingCa.pkey, port->secure));
     fd_table[clientConnection->fd].dynamicTlsContext = unConfiguredCTX;
 
-    if (!httpsCreate(clientConnection, unConfiguredCTX))
+    if (!httpsCreate(this, unConfiguredCTX))
         return;
 
     switchedToHttps_ = true;
diff -u -r -N squid-4.7/src/comm/TcpAcceptor.cc squid-4.8/src/comm/TcpAcceptor.cc
--- squid-4.7/src/comm/TcpAcceptor.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/comm/TcpAcceptor.cc	2019-07-10 07:05:20.000000000 +1200
@@ -361,10 +361,10 @@
 
         PROF_stop(comm_accept);
 
-        if (ignoreErrno(errcode)) {
+        if (ignoreErrno(errcode) || errcode == ECONNABORTED) {
             debugs(50, 5, status() << ": " << xstrerr(errcode));
             return Comm::NOMESSAGE;
-        } else if (ENFILE == errno || EMFILE == errno) {
+        } else if (errcode == ENFILE || errcode == EMFILE) {
             debugs(50, 3, status() << ": " << xstrerr(errcode));
             return Comm::COMM_ERROR;
         } else {
diff -u -r -N squid-4.7/src/enums.h squid-4.8/src/enums.h
--- squid-4.7/src/enums.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/enums.h	2019-07-10 07:05:20.000000000 +1200
@@ -10,7 +10,7 @@
 #define SQUID_ENUMS_H
 
 enum fd_type {
-    FD_NONE,
+    FD_NONE_TYPE,
     FD_LOG,
     FD_FILE,
     FD_SOCKET,
diff -u -r -N squid-4.7/src/http/one/ResponseParser.cc squid-4.8/src/http/one/ResponseParser.cc
--- squid-4.7/src/http/one/ResponseParser.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/http/one/ResponseParser.cc	2019-07-10 07:05:20.000000000 +1200
@@ -159,8 +159,13 @@
         debugs(74, DBG_DATA, "parse remaining buf={length=" << tok.remaining().length() << ", data='" << tok.remaining() << "'}");
         buf_ = tok.remaining(); // resume checkpoint
         return parseResponseStatusAndReason(tok, WspDelim);
-
-    } else if (buf_.length() > Http1magic.length() && buf_.length() > IcyMagic.length()) {
+    } else if (buf_.length() < Http1magic.length() && Http1magic.startsWith(buf_)) {
+        debugs(74, 7, Raw("valid HTTP/1 prefix", buf_.rawContent(), buf_.length()));
+        return 0;
+    } else if (buf_.length() < IcyMagic.length() && IcyMagic.startsWith(buf_)) {
+        debugs(74, 7, Raw("valid ICY prefix", buf_.rawContent(), buf_.length()));
+        return 0;
+    } else {
         debugs(74, 2, "unknown/missing prefix magic. Interpreting as HTTP/0.9");
         // found something that looks like an HTTP/0.9 response
         // Gateway/Transform it into HTTP/1.1
@@ -180,7 +185,9 @@
         return 1; // no more parsing
     }
 
-    return 0; // need more to parse anything.
+    // unreachable
+    assert(false);
+    return -1;
 }
 
 bool
diff -u -r -N squid-4.7/src/http/StateFlags.h squid-4.8/src/http/StateFlags.h
--- squid-4.7/src/http/StateFlags.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/http/StateFlags.h	2019-07-10 07:05:20.000000000 +1200
@@ -17,7 +17,7 @@
 public:
     unsigned int front_end_https = 0; ///< send "Front-End-Https: On" header (off/on/auto=2)
     bool proxying = false;
-    bool keepalive = false;
+    bool keepalive = false; ///< whether to keep the connection persistent
     bool only_if_cached = false;
     bool handling1xx = false;       ///< we are ignoring or forwarding 1xx response
     bool headers_parsed = false;
diff -u -r -N squid-4.7/src/http/url_rewriters/LFS/url_lfs_rewrite.8 squid-4.8/src/http/url_rewriters/LFS/url_lfs_rewrite.8
--- squid-4.7/src/http/url_rewriters/LFS/url_lfs_rewrite.8	2019-05-07 02:07:35.000000000 +1200
+++ squid-4.8/src/http/url_rewriters/LFS/url_lfs_rewrite.8	2019-07-10 07:25:14.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "URL_LFS_REWRITE 8"
-.TH URL_LFS_REWRITE 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH URL_LFS_REWRITE 8 "2019-07-09" "perl v5.28.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-4.7/src/http.cc squid-4.8/src/http.cc
--- squid-4.7/src/http.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/http.cc	2019-07-10 07:05:20.000000000 +1200
@@ -1909,10 +1909,10 @@
         delete cc;
     }
 
-    /* maybe append Connection: keep-alive */
-    if (flags.keepalive) {
-        hdr_out->putStr(Http::HdrType::CONNECTION, "keep-alive");
-    }
+    // Always send Connection because HTTP/1.0 servers need explicit "keep-alive"
+    // while HTTP/1.1 servers need explicit "close", and we do not always know
+    // the server expectations.
+    hdr_out->putStr(Http::HdrType::CONNECTION, flags.keepalive ? "keep-alive" : "close");
 
     /* append Front-End-Https */
     if (flags.front_end_https) {
diff -u -r -N squid-4.7/src/HttpHeader.cc squid-4.8/src/HttpHeader.cc
--- squid-4.7/src/HttpHeader.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/HttpHeader.cc	2019-07-10 07:05:20.000000000 +1200
@@ -1268,43 +1268,46 @@
     return cr;
 }
 
-const char *
-HttpHeader::getAuth(Http::HdrType id, const char *auth_scheme) const
+SBuf
+HttpHeader::getAuthToken(Http::HdrType id, const char *auth_scheme) const
 {
     const char *field;
     int l;
     assert(auth_scheme);
     field = getStr(id);
 
+    static const SBuf nil;
     if (!field)         /* no authorization field */
-        return NULL;
+        return nil;
 
     l = strlen(auth_scheme);
 
     if (!l || strncasecmp(field, auth_scheme, l))   /* wrong scheme */
-        return NULL;
+        return nil;
 
     field += l;
 
     if (!xisspace(*field))  /* wrong scheme */
-        return NULL;
+        return nil;
 
     /* skip white space */
     for (; field && xisspace(*field); ++field);
 
     if (!*field)        /* no authorization cookie */
-        return NULL;
+        return nil;
 
-    static char decodedAuthToken[8192];
+    const auto fieldLen = strlen(field);
+    SBuf result;
+    char *decodedAuthToken = result.rawAppendStart(BASE64_DECODE_LENGTH(fieldLen));
     struct base64_decode_ctx ctx;
     base64_decode_init(&ctx);
     size_t decodedLen = 0;
-    if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), strlen(field), field) ||
+    if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), fieldLen, field) ||
             !base64_decode_final(&ctx)) {
-        return NULL;
+        return nil;
     }
-    decodedAuthToken[decodedLen] = '\0';
-    return decodedAuthToken;
+    result.rawAppendFinish(decodedAuthToken, decodedLen);
+    return result;
 }
 
 ETag
diff -u -r -N squid-4.7/src/HttpHeader.h squid-4.8/src/HttpHeader.h
--- squid-4.7/src/HttpHeader.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/HttpHeader.h	2019-07-10 07:05:20.000000000 +1200
@@ -134,7 +134,7 @@
     HttpHdrRange *getRange() const;
     HttpHdrSc *getSc() const;
     HttpHdrContRange *getContRange() const;
-    const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
+    SBuf getAuthToken(Http::HdrType id, const char *auth_scheme) const;
     ETag getETag(Http::HdrType id) const;
     TimeOrTag getTimeOrTag(Http::HdrType id) const;
     int hasListMember(Http::HdrType id, const char *member, const char separator) const;
diff -u -r -N squid-4.7/src/HttpReply.cc squid-4.8/src/HttpReply.cc
--- squid-4.7/src/HttpReply.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/HttpReply.cc	2019-07-10 07:05:20.000000000 +1200
@@ -477,6 +477,7 @@
         expectBody = false;
     else if (sline.status() == Http::scNotModified)
         expectBody = false;
+    // TODO: Consider assuming that gray-area 0xx responses have bodies, like 9xx responses.
     else if (sline.status() < Http::scOkay)
         expectBody = false;
     else
diff -u -r -N squid-4.7/src/ipc/SharedListen.cc squid-4.8/src/ipc/SharedListen.cc
--- squid-4.7/src/ipc/SharedListen.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/ipc/SharedListen.cc	2019-07-10 07:05:20.000000000 +1200
@@ -54,11 +54,6 @@
     return -1;
 }
 
-Ipc::OpenListenerParams::OpenListenerParams()
-{
-    memset(this, 0, sizeof(*this));
-}
-
 bool
 Ipc::OpenListenerParams::operator <(const OpenListenerParams &p) const
 {
diff -u -r -N squid-4.7/src/ipc/SharedListen.h squid-4.8/src/ipc/SharedListen.h
--- squid-4.7/src/ipc/SharedListen.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/ipc/SharedListen.h	2019-07-10 07:05:20.000000000 +1200
@@ -24,18 +24,16 @@
 class OpenListenerParams
 {
 public:
-    OpenListenerParams();
-
     bool operator <(const OpenListenerParams &p) const; ///< useful for map<>
 
     // bits to re-create the fde entry
-    int sock_type;
-    int proto;
-    int fdNote; ///< index into fd_note() comment strings
+    int sock_type = 0;
+    int proto = 0;
+    int fdNote = 0; ///< index into fd_note() comment strings
 
     // bits to re-create the listener Comm::Connection descriptor
     Ip::Address addr; ///< will be memset and memcopied
-    int flags;
+    int flags = 0;
 
     /// handler to subscribe to Comm::ConnAcceptor when we get the response
     Subscription::Pointer handlerSubscription;
diff -u -r -N squid-4.7/src/log/DB/log_db_daemon.8 squid-4.8/src/log/DB/log_db_daemon.8
--- squid-4.7/src/log/DB/log_db_daemon.8	2019-05-07 02:07:35.000000000 +1200
+++ squid-4.8/src/log/DB/log_db_daemon.8	2019-07-10 07:25:14.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "LOG_DB_DAEMON 8"
-.TH LOG_DB_DAEMON 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH LOG_DB_DAEMON 8 "2019-07-09" "perl v5.28.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-4.7/src/mgr/InfoAction.cc squid-4.8/src/mgr/InfoAction.cc
--- squid-4.7/src/mgr/InfoAction.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/mgr/InfoAction.cc	2019-07-10 07:05:20.000000000 +1200
@@ -28,11 +28,6 @@
 void DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry);
 void DumpMallocStatistics(StoreEntry* sentry);
 
-Mgr::InfoActionData::InfoActionData()
-{
-    memset(this, 0, sizeof(*this));
-}
-
 Mgr::InfoActionData&
 Mgr::InfoActionData::operator += (const InfoActionData& stats)
 {
diff -u -r -N squid-4.7/src/mgr/InfoAction.h squid-4.8/src/mgr/InfoAction.h
--- squid-4.7/src/mgr/InfoAction.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/mgr/InfoAction.h	2019-07-10 07:05:20.000000000 +1200
@@ -22,73 +22,72 @@
 class InfoActionData
 {
 public:
-    InfoActionData();
     InfoActionData& operator += (const InfoActionData& stats);
 
 public:
-    struct timeval squid_start;
-    struct timeval current_time;
-    double client_http_clients;
-    double client_http_requests;
-    double icp_pkts_recv;
-    double icp_pkts_sent;
-    double icp_replies_queued;
+    struct timeval squid_start = {};
+    struct timeval current_time = {};
+    double client_http_clients = 0.0;
+    double client_http_requests = 0.0;
+    double icp_pkts_recv = 0.0;
+    double icp_pkts_sent = 0.0;
+    double icp_replies_queued = 0.0;
 #if USE_HTCP
-    double htcp_pkts_recv;
-    double htcp_pkts_sent;
+    double htcp_pkts_recv = 0.0;
+    double htcp_pkts_sent = 0.0;
 #endif
-    double request_failure_ratio;
-    double avg_client_http_requests;
-    double avg_icp_messages;
-    double select_loops;
-    double avg_loop_time;
-    double request_hit_ratio5;
-    double request_hit_ratio60;
-    double byte_hit_ratio5;
-    double byte_hit_ratio60;
-    double request_hit_mem_ratio5;
-    double request_hit_mem_ratio60;
-    double request_hit_disk_ratio5;
-    double request_hit_disk_ratio60;
+    double request_failure_ratio = 0.0;
+    double avg_client_http_requests = 0.0;
+    double avg_icp_messages = 0.0;
+    double select_loops = 0.0;
+    double avg_loop_time = 0.0;
+    double request_hit_ratio5 = 0.0;
+    double request_hit_ratio60 = 0.0;
+    double byte_hit_ratio5 = 0.0;
+    double byte_hit_ratio60 = 0.0;
+    double request_hit_mem_ratio5 = 0.0;
+    double request_hit_mem_ratio60 = 0.0;
+    double request_hit_disk_ratio5 = 0.0;
+    double request_hit_disk_ratio60 = 0.0;
 
     StoreInfoStats store; ///< disk and memory cache statistics
 
-    double unlink_requests;
-    double http_requests5;
-    double http_requests60;
-    double cache_misses5;
-    double cache_misses60;
-    double cache_hits5;
-    double cache_hits60;
-    double near_hits5;
-    double near_hits60;
-    double not_modified_replies5;
-    double not_modified_replies60;
-    double dns_lookups5;
-    double dns_lookups60;
-    double icp_queries5;
-    double icp_queries60;
-    double up_time;
-    double cpu_time;
-    double cpu_usage;
-    double cpu_usage5;
-    double cpu_usage60;
-    double maxrss;
-    double page_faults;
+    double unlink_requests = 0.0;
+    double http_requests5 = 0.0;
+    double http_requests60 = 0.0;
+    double cache_misses5 = 0.0;
+    double cache_misses60 = 0.0;
+    double cache_hits5 = 0.0;
+    double cache_hits60 = 0.0;
+    double near_hits5 = 0.0;
+    double near_hits60 = 0.0;
+    double not_modified_replies5 = 0.0;
+    double not_modified_replies60 = 0.0;
+    double dns_lookups5 = 0.0;
+    double dns_lookups60 = 0.0;
+    double icp_queries5 = 0.0;
+    double icp_queries60 = 0.0;
+    double up_time = 0.0;
+    double cpu_time = 0.0;
+    double cpu_usage = 0.0;
+    double cpu_usage5 = 0.0;
+    double cpu_usage60 = 0.0;
+    double maxrss = 0.0;
+    double page_faults = 0.0;
 #if HAVE_MSTATS && HAVE_GNUMALLOC_H
-    double ms_bytes_total;
-    double ms_bytes_free;
+    double ms_bytes_total = 0.0;
+    double ms_bytes_free = 0.0;
 #endif
-    double total_accounted;
-    double gb_saved_count;
-    double gb_freed_count;
-    double max_fd;
-    double biggest_fd;
-    double number_fd;
-    double opening_fd;
-    double num_fd_free;
-    double reserved_fd;
-    unsigned int count;
+    double total_accounted = 0.0;
+    double gb_saved_count = 0.0;
+    double gb_freed_count = 0.0;
+    double max_fd = 0.0;
+    double biggest_fd = 0.0;
+    double number_fd = 0.0;
+    double opening_fd = 0.0;
+    double num_fd_free = 0.0;
+    double reserved_fd = 0.0;
+    unsigned int count = 0;
 };
 
 /// implement aggregated 'info' action
diff -u -r -N squid-4.7/src/security/cert_validators/fake/security_fake_certverify.8 squid-4.8/src/security/cert_validators/fake/security_fake_certverify.8
--- squid-4.7/src/security/cert_validators/fake/security_fake_certverify.8	2019-05-07 02:07:36.000000000 +1200
+++ squid-4.8/src/security/cert_validators/fake/security_fake_certverify.8	2019-07-10 07:25:14.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "SECURITY_FAKE_CERTVERIFY 8"
-.TH SECURITY_FAKE_CERTVERIFY 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH SECURITY_FAKE_CERTVERIFY 8 "2019-07-09" "perl v5.28.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-4.7/src/security/PeerOptions.cc squid-4.8/src/security/PeerOptions.cc
--- squid-4.7/src/security/PeerOptions.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/security/PeerOptions.cc	2019-07-10 07:05:20.000000000 +1200
@@ -53,13 +53,14 @@
         KeyData &t = certs.back();
         t.privateKeyFile = SBuf(token + 4);
     } else if (strncmp(token, "version=", 8) == 0) {
-        debugs(0, DBG_PARSE_NOTE(1), "UPGRADE WARNING: SSL version= is deprecated. Use options= to limit protocols instead.");
+        debugs(0, DBG_PARSE_NOTE(1), "UPGRADE WARNING: SSL version= is deprecated. Use options= and tls-min-version= to limit protocols instead.");
         sslVersion = xatoi(token + 8);
     } else if (strncmp(token, "min-version=", 12) == 0) {
         tlsMinVersion = SBuf(token + 12);
+        optsReparse = true;
     } else if (strncmp(token, "options=", 8) == 0) {
         sslOptions = SBuf(token + 8);
-        parseOptions();
+        optsReparse = true;
     } else if (strncmp(token, "cipher=", 7) == 0) {
         sslCipher = SBuf(token + 7);
     } else if (strncmp(token, "cafile=", 7) == 0) {
@@ -152,37 +153,31 @@
     if (!tlsMinVersion.isEmpty()) {
         ::Parser::Tokenizer tok(tlsMinVersion);
         int64_t v = 0;
+        tlsMinOptions.clear();
         if (tok.skip('1') && tok.skip('.') && tok.int64(v, 10, false, 1) && v <= 3) {
             // only account for TLS here - SSL versions are handled by options= parameter
             // avoid affecting options= parameter in cachemgr config report
+            SBuf add;
 #if USE_OPENSSL
-#if SSL_OP_NO_TLSv1
             if (v > 0)
-                parsedOptions |= SSL_OP_NO_TLSv1;
-#endif
-#if SSL_OP_NO_TLSv1_1
+                add.append(":NO_TLSv1");
             if (v > 1)
-                parsedOptions |= SSL_OP_NO_TLSv1_1;
-#endif
-#if SSL_OP_NO_TLSv1_2
+                add.append(":NO_TLSv1_1");
             if (v > 2)
-                parsedOptions |= SSL_OP_NO_TLSv1_2;
-#endif
-
+                add.append(":NO_TLSv1_2");
 #elif USE_GNUTLS
-            // XXX: update parsedOptions directly to avoid polluting 'options=' dumps
-            SBuf add;
             if (v > 0)
                 add.append(":-VERS-TLS1.0");
             if (v > 1)
                 add.append(":-VERS-TLS1.1");
             if (v > 2)
                 add.append(":-VERS-TLS1.2");
+#endif
 
-            if (sslOptions.isEmpty())
+            if (!tlsMinOptions.isEmpty())
                 add.chop(1); // remove the initial ':'
-            sslOptions.append(add);
-#endif
+            tlsMinOptions.append(add);
+            optsReparse = true;
 
         } else {
             debugs(0, DBG_PARSE_NOTE(1), "WARNING: Unknown TLS minimum version: " << tlsMinVersion);
@@ -200,42 +195,41 @@
         switch (sslVersion) {
         case 3:
 #if USE_OPENSSL
-            parsedOptions |= (SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2);
+            add = ":NO_TLSv1:NO_TLSv1_1:NO_TLSv1_2:NO_TLSv1_3";
 #elif USE_GNUTLS
-            add = ":-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2";
+            add = ":-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2:-VERS-TLS1.3";
 #endif
             break;
         case 4:
 #if USE_OPENSSL
-            parsedOptions |= (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2);
+            add = ":NO_SSLv3:NO_TLSv1_1:NO_TLSv1_2:NO_TLSv1_3";
 #elif USE_GNUTLS
-            add = ":+VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2";
+            add = ":+VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.2:-VERS-TLS1.3";
 #endif
             break;
         case 5:
 #if USE_OPENSSL
-            parsedOptions |= (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_2);
+            add = ":NO_SSLv3:NO_TLSv1:NO_TLSv1_2:NO_TLSv1_3";
 #elif USE_GNUTLS
-            add = ":-VERS-TLS1.0:+VERS-TLS1.1:-VERS-TLS1.2";
+            add = ":-VERS-TLS1.0:+VERS-TLS1.1:-VERS-TLS1.2:-VERS-TLS1.3";
 #endif
             break;
         case 6:
 #if USE_OPENSSL
-            parsedOptions |= (SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1);
+            add = ":NO_SSLv3:NO_TLSv1:NO_TLSv1_1:NO_TLSv1_3";
 #elif USE_GNUTLS
-            add = ":-VERS-TLS1.0:-VERS-TLS1.1";
+            add = ":-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.3";
 #endif
             break;
         default: // nothing
             break;
         }
         if (add) {
-#if USE_GNUTLS // do not bother otherwise
             if (sslOptions.isEmpty())
                 sslOptions.append(add+1, strlen(add+1));
             else
                 sslOptions.append(add, strlen(add));
-#endif
+            optsReparse = true;
         }
         sslVersion = 0; // prevent sslOptions being repeatedly appended
     }
@@ -390,16 +384,29 @@
     {
         "NO_TLSv1", SSL_OP_NO_TLSv1
     },
+#else
+    { "NO_TLSv1", 0 },
 #endif
 #if SSL_OP_NO_TLSv1_1
     {
         "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
     },
+#else
+    { "NO_TLSv1_1", 0 },
 #endif
 #if SSL_OP_NO_TLSv1_2
     {
         "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
     },
+#else
+    { "NO_TLSv1_2", 0 },
+#endif
+#if SSL_OP_NO_TLSv1_3
+    {
+        "NO_TLSv1_3", SSL_OP_NO_TLSv1_3
+    },
+#else
+    { "NO_TLSv1_3", 0 },
 #endif
 #if SSL_OP_NO_COMPRESSION
     {
@@ -432,8 +439,20 @@
 void
 Security::PeerOptions::parseOptions()
 {
+    // do not allow repeated parsing when multiple contexts are created
+    // NP: we cannot use !parsedOptions because a nil value does have meaning there
+    if (!optsReparse)
+        return;
+    optsReparse = false;
+
+    // combination of settings we have to set via parsedOptions.
+    // options= with override by tls-min-version=
+    SBuf str;
+    str.append(sslOptions);
+    str.append(tlsMinOptions);
+
 #if USE_OPENSSL
-    ::Parser::Tokenizer tok(sslOptions);
+    ::Parser::Tokenizer tok(str);
     long op = 0;
 
     while (!tok.atEnd()) {
@@ -498,16 +517,17 @@
     parsedOptions = op;
 
 #elif USE_GNUTLS
-    if (sslOptions.isEmpty()) {
+    if (str.isEmpty()) {
         parsedOptions.reset();
         return;
     }
 
     const char *err = nullptr;
-    const char *priorities = sslOptions.c_str();
+    const char *priorities = str.c_str();
     gnutls_priority_t op;
-    if (gnutls_priority_init(&op, priorities, &err) != GNUTLS_E_SUCCESS) {
-        fatalf("Unknown TLS option '%s'", err);
+    int x = gnutls_priority_init(&op, priorities, &err);
+    if (x != GNUTLS_E_SUCCESS) {
+        fatalf("(%s) in TLS options '%s'", ErrorString(x), err);
     }
     parsedOptions = Security::ParsedOptions(op, [](gnutls_priority_t p) {
         debugs(83, 5, "gnutls_priority_deinit p=" << (void*)p);
@@ -591,12 +611,13 @@
 }
 
 void
-Security::PeerOptions::updateContextOptions(Security::ContextPointer &ctx) const
+Security::PeerOptions::updateContextOptions(Security::ContextPointer &ctx)
 {
+    parseOptions();
 #if USE_OPENSSL
     SSL_CTX_set_options(ctx.get(), parsedOptions);
 #elif USE_GNUTLS
-    // NP: GnuTLS uses 'priorities' which are set per-session instead.
+    // NP: GnuTLS uses 'priorities' which are set only per-session instead.
 #endif
 }
 
@@ -723,8 +744,12 @@
 void
 Security::PeerOptions::updateSessionOptions(Security::SessionPointer &s)
 {
+    parseOptions();
 #if USE_OPENSSL
-    // 'options=' value being set to session is a GnuTLS specific thing.
+    debugs(83, 5, "set OpenSSL options for session=" << s << ", parsedOptions=" << parsedOptions);
+    // XXX: Options already set before (via the context) are not cleared!
+    SSL_set_options(s.get(), parsedOptions);
+
 #elif USE_GNUTLS
     int x;
     SBuf errMsg;
@@ -734,13 +759,13 @@
         static const SBuf defaults("default");
         errMsg = defaults;
     } else {
-        debugs(83, 5, "set GnuTLS options '" << sslOptions << "' for session=" << s);
+        debugs(83, 5, "set GnuTLS session=" << s << ", options='" << sslOptions << ":" << tlsMinOptions << "'");
         x = gnutls_priority_set(s.get(), parsedOptions.get());
         errMsg = sslOptions;
     }
 
     if (x != GNUTLS_E_SUCCESS) {
-        debugs(83, DBG_IMPORTANT, "ERROR: Failed to set TLS options (" << errMsg << "). error: " << Security::ErrorString(x));
+        debugs(83, DBG_IMPORTANT, "ERROR: session=" << s << " Failed to set TLS options (" << errMsg << ":" << tlsMinVersion << "). error: " << Security::ErrorString(x));
     }
 #endif
 }
@@ -750,5 +775,6 @@
 {
     while(const char *token = ConfigParser::NextToken())
         opt->parse(token);
+    opt->parseOptions();
 }
 
diff -u -r -N squid-4.7/src/security/PeerOptions.h squid-4.8/src/security/PeerOptions.h
--- squid-4.7/src/security/PeerOptions.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/security/PeerOptions.h	2019-07-10 07:05:20.000000000 +1200
@@ -32,6 +32,9 @@
     /// parse a TLS squid.conf option
     virtual void parse(const char *);
 
+    /// parse and verify the [tls-]options= string in sslOptions
+    void parseOptions();
+
     /// reset the configuration details to default
     virtual void clear() {*this = PeerOptions();}
 
@@ -45,7 +48,7 @@
     void updateTlsVersionLimits();
 
     /// Setup the library specific 'options=' parameters for the given context.
-    void updateContextOptions(Security::ContextPointer &) const;
+    void updateContextOptions(Security::ContextPointer &);
 
     /// setup the NPN extension details for the given context
     void updateContextNpn(Security::ContextPointer &);
@@ -66,7 +69,6 @@
     virtual void dumpCfg(Packable *, const char *pfx) const;
 
 private:
-    void parseOptions(); ///< parsed value of sslOptions
     long parseFlags();
     void loadCrlFile();
     void loadKeysFile();
@@ -82,7 +84,19 @@
 
     SBuf tlsMinVersion;  ///< version label for minimum TLS version to permit
 
-    Security::ParsedOptions parsedOptions; ///< parsed value of sslOptions
+private:
+    /// Library-specific options string generated from tlsMinVersion.
+    /// Call updateTlsVersionLimits() to regenerate this string.
+    SBuf tlsMinOptions;
+
+    /// Parsed value of sslOptions + tlsMinOptions settings.
+    /// Set optsReparse=true to have this re-parsed before next use.
+    Security::ParsedOptions parsedOptions;
+
+    /// whether parsedOptions content needs to be regenerated
+    bool optsReparse = true;
+
+public:
     long parsedFlags = 0;   ///< parsed value of sslFlags
 
     std::list<Security::KeyData> certs; ///< details from the cert= and file= config parameters
@@ -93,13 +107,15 @@
     template<typename T>
     Security::ContextPointer convertContextFromRawPtr(T ctx) const {
 #if USE_OPENSSL
+        debugs(83, 5, "SSL_CTX construct, this=" << (void*)ctx);
         return ContextPointer(ctx, [](SSL_CTX *p) {
-            debugs(83, 5, "SSL_free ctx=" << (void*)p);
+            debugs(83, 5, "SSL_CTX destruct, this=" << (void*)p);
             SSL_CTX_free(p);
         });
 #elif USE_GNUTLS
+        debugs(83, 5, "gnutls_certificate_credentials construct, this=" << (void*)ctx);
         return Security::ContextPointer(ctx, [](gnutls_certificate_credentials_t p) {
-            debugs(83, 5, "gnutls_certificate_free_credentials ctx=" << (void*)p);
+            debugs(83, 0, "gnutls_certificate_credentials destruct this=" << (void*)p);
             gnutls_certificate_free_credentials(p);
         });
 #else
diff -u -r -N squid-4.7/src/security/Session.cc squid-4.8/src/security/Session.cc
--- squid-4.7/src/security/Session.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/security/Session.cc	2019-07-10 07:05:20.000000000 +1200
@@ -106,7 +106,7 @@
 #endif
 
 static bool
-CreateSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &conn, Security::Io::Type type, const char *squidCtx)
+CreateSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &conn, Security::PeerOptions &opts, Security::Io::Type type, const char *squidCtx)
 {
     if (!Comm::IsConnOpen(conn)) {
         debugs(83, DBG_IMPORTANT, "Gone connection");
@@ -122,6 +122,7 @@
     if (!session) {
         errCode = ERR_get_error();
         errAction = "failed to allocate handle";
+        debugs(83, DBG_IMPORTANT, "TLS error: " << errAction << ": " << Security::ErrorString(errCode));
     }
 #elif USE_GNUTLS
     gnutls_session_t tmp;
@@ -134,6 +135,7 @@
     if (errCode != GNUTLS_E_SUCCESS) {
         session.reset();
         errAction = "failed to initialize session";
+        debugs(83, DBG_IMPORTANT, "TLS error: " << errAction << ": " << Security::ErrorString(errCode));
     }
 #endif
 
@@ -148,10 +150,7 @@
         errCode = gnutls_credentials_set(session.get(), GNUTLS_CRD_CERTIFICATE, ctx.get());
         if (errCode == GNUTLS_E_SUCCESS) {
 
-            if (auto *peer = conn->getPeer())
-                peer->secure.updateSessionOptions(session);
-            else
-                Security::ProxyOutgoingConfig.updateSessionOptions(session);
+            opts.updateSessionOptions(session);
 
             // NP: GnuTLS does not yet support the BIO operations
             //     this does the equivalent of SSL_set_fd() for now.
@@ -184,13 +183,17 @@
 bool
 Security::CreateClientSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &c, const char *squidCtx)
 {
-    return CreateSession(ctx, c, Security::Io::BIO_TO_SERVER, squidCtx);
+    if (!c || !c->getPeer())
+        return CreateSession(ctx, c, Security::ProxyOutgoingConfig, Security::Io::BIO_TO_SERVER, squidCtx);
+
+    auto *peer = c->getPeer();
+    return CreateSession(ctx, c, peer->secure, Security::Io::BIO_TO_SERVER, squidCtx);
 }
 
 bool
-Security::CreateServerSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &c, const char *squidCtx)
+Security::CreateServerSession(const Security::ContextPointer &ctx, const Comm::ConnectionPointer &c, Security::PeerOptions &o, const char *squidCtx)
 {
-    return CreateSession(ctx, c, Security::Io::BIO_TO_CLIENT, squidCtx);
+    return CreateSession(ctx, c, o, Security::Io::BIO_TO_CLIENT, squidCtx);
 }
 
 void
diff -u -r -N squid-4.7/src/security/Session.h squid-4.8/src/security/Session.h
--- squid-4.7/src/security/Session.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/security/Session.h	2019-07-10 07:05:20.000000000 +1200
@@ -34,9 +34,11 @@
 /// On errors, emits DBG_IMPORTANT with details and returns false.
 bool CreateClientSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *squidCtx);
 
+class PeerOptions;
+
 /// Creates TLS Server connection structure (aka 'session' state) and initializes TLS/SSL I/O (Comm and BIO).
 /// On errors, emits DBG_IMPORTANT with details and returns false.
-bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *squidCtx);
+bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, Security::PeerOptions &, const char *squidCtx);
 
 #if USE_OPENSSL
 typedef std::shared_ptr<SSL> SessionPointer;
diff -u -r -N squid-4.7/src/servers/Http1Server.cc squid-4.8/src/servers/Http1Server.cc
--- squid-4.7/src/servers/Http1Server.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/servers/Http1Server.cc	2019-07-10 07:05:20.000000000 +1200
@@ -305,6 +305,7 @@
     }
 
     assert(rep);
+    HTTPMSGUNLOCK(http->al->reply);
     http->al->reply = rep;
     HTTPMSGLOCK(http->al->reply);
     context->sendStartOfMessage(rep, receivedData);
diff -u -r -N squid-4.7/src/ssl/PeekingPeerConnector.cc squid-4.8/src/ssl/PeekingPeerConnector.cc
--- squid-4.7/src/ssl/PeekingPeerConnector.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/ssl/PeekingPeerConnector.cc	2019-07-10 07:05:20.000000000 +1200
@@ -185,7 +185,7 @@
             srvBio->mode(csd->sslBumpMode);
         } else {
             // Set client SSL options
-            SSL_set_options(serverSession.get(), ::Security::ProxyOutgoingConfig.parsedOptions);
+            ::Security::ProxyOutgoingConfig.updateSessionOptions(serverSession);
 
             const bool redirected = request->flags.redirected && ::Config.onoff.redir_rewrites_host;
             const char *sniServer = (!hostName || redirected) ?
diff -u -r -N squid-4.7/src/store/id_rewriters/file/storeid_file_rewrite.8 squid-4.8/src/store/id_rewriters/file/storeid_file_rewrite.8
--- squid-4.7/src/store/id_rewriters/file/storeid_file_rewrite.8	2019-05-07 02:07:34.000000000 +1200
+++ squid-4.8/src/store/id_rewriters/file/storeid_file_rewrite.8	2019-07-10 07:25:12.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "STOREID_FILE_REWRITE 8"
-.TH STOREID_FILE_REWRITE 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH STOREID_FILE_REWRITE 8 "2019-07-09" "perl v5.28.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-4.7/src/StoreStats.cc squid-4.8/src/StoreStats.cc
--- squid-4.7/src/StoreStats.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/StoreStats.cc	2019-07-10 07:05:20.000000000 +1200
@@ -12,13 +12,6 @@
 #include "StoreStats.h"
 #include "tools.h"
 
-/* StoreInfoStats */
-
-StoreInfoStats::StoreInfoStats()
-{
-    memset(this, 0, sizeof(*this));
-}
-
 StoreInfoStats &
 StoreInfoStats::operator +=(const StoreInfoStats &stats)
 {
diff -u -r -N squid-4.7/src/StoreStats.h squid-4.8/src/StoreStats.h
--- squid-4.7/src/StoreStats.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/StoreStats.h	2019-07-10 07:05:20.000000000 +1200
@@ -17,9 +17,9 @@
     class Part
     {
     public:
-        double size; ///< bytes currently in use
-        double count; ///< number of cached objects
-        double capacity; ///< the size limit
+        double size = 0.0; ///< bytes currently in use
+        double count = 0.0; ///< number of cached objects
+        double capacity = 0.0; ///< the size limit
 
         /// mean size of a cached object
         double meanObjectSize() const { return count > 0 ? size/count : 0.0; }
@@ -32,25 +32,24 @@
     class Swap: public Part
     {
     public:
-        double open_disk_fd; ///< number of opened disk files
+        double open_disk_fd = 0.0; ///< number of opened disk files
     };
 
     /// memory cache (cache_mem) storage stats
     class Mem: public Part
     {
     public:
-        bool shared; ///< whether memory cache is shared among workers
+        bool shared = false; ///< whether memory cache is shared among workers
     };
 
-    StoreInfoStats();
     StoreInfoStats &operator +=(const StoreInfoStats &stats);
 
     Swap swap; ///< cache_mem stats
     Mem mem; ///< all cache_dirs stats
 
     /* stats that could be shared by memory and disk storage */
-    double store_entry_count; ///< number of StoreEntry objects in existence
-    double mem_object_count; ///< number of MemObject objects in existence
+    double store_entry_count = 0.0; ///< number of StoreEntry objects in existence
+    double mem_object_count = 0.0; ///< number of MemObject objects in existence
 };
 
 // TODO: this should be adjusted for use in StoreIoActionData, DiskdActionData
diff -u -r -N squid-4.7/src/StoreSwapLogData.cc squid-4.8/src/StoreSwapLogData.cc
--- squid-4.7/src/StoreSwapLogData.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/StoreSwapLogData.cc	2019-07-10 07:05:20.000000000 +1200
@@ -49,11 +49,6 @@
     return os << raw[0] << '-' << raw[1] << '-' << raw[2];
 }
 
-StoreSwapLogData::StoreSwapLogData()
-{
-    memset(this, 0, sizeof(*this));
-}
-
 bool
 StoreSwapLogData::sane() const
 {
diff -u -r -N squid-4.7/src/StoreSwapLogData.h squid-4.8/src/StoreSwapLogData.h
--- squid-4.7/src/StoreSwapLogData.h	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/StoreSwapLogData.h	2019-07-10 07:05:20.000000000 +1200
@@ -90,8 +90,6 @@
     /// type to use for storing time-related members; must be signed
     typedef int64_t SwappedTime;
 
-    StoreSwapLogData();
-
     /// consistency self-check: whether the data appears to make sense
     bool sane() const;
 
@@ -102,7 +100,7 @@
      * Either SWAP_LOG_ADD when an object is added to the disk storage,
      * or SWAP_LOG_DEL when an object is deleted.
      */
-    uint8_t op;
+    uint8_t op = 0;
 
     /**
      * Fingerprint to weed out bogus/corrupted swap.state entries.
@@ -116,7 +114,7 @@
      * are set at run time because the order of storage directories
      * may change over time.
      */
-    sfileno swap_filen;
+    sfileno swap_filen = 0;
 
     /**
      * A Unix time value that represents the time when
@@ -125,12 +123,12 @@
      * to that time. Otherwise, it is set to the Squid process time
      * when the response is read (as soon as the end of headers are found).
      */
-    SwappedTime timestamp;
+    SwappedTime timestamp = 0;
 
     /**
      * The last time that a client requested this object.
      */
-    SwappedTime lastref;
+    SwappedTime lastref = 0;
 
     /**
      * The value of the response's Expires: header, if any.
@@ -141,20 +139,20 @@
      * where Squid sets expires to -2. This happens for the
      * internal "netdb" object and for FTP URL responses.
      */
-    SwappedTime expires;
+    SwappedTime expires = 0;
 
     /**
      * The value of the response's Last-modified: header, if any.
      * This is set to -1 if there is no Last-modified: header,
      * or if it is unparseable.
      */
-    SwappedTime lastmod;
+    SwappedTime lastmod = 0;
 
     /**
      * This is the number of bytes that the object occupies on
      * disk. It includes the Squid "swap file header".
      */
-    uint64_t swap_file_sz;
+    uint64_t swap_file_sz = 0;
 
     /**
      * The number of times that this object has been accessed (referenced).
@@ -168,12 +166,12 @@
      * check when rebuilding the cache at startup. Objects that
      * have the KEY_PRIVATE flag set are not added back to the cache.
      */
-    uint16_t flags;
+    uint16_t flags = 0;
 
     /**
      * The 128-bit MD5 hash for this object.
      */
-    unsigned char key[SQUID_MD5_DIGEST_LENGTH];
+    unsigned char key[SQUID_MD5_DIGEST_LENGTH] = {};
 };
 
 /// \ingroup FileFormatSwapStateAPI
diff -u -r -N squid-4.7/src/tests/stub_libsecurity.cc squid-4.8/src/tests/stub_libsecurity.cc
--- squid-4.7/src/tests/stub_libsecurity.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/tests/stub_libsecurity.cc	2019-07-10 07:05:20.000000000 +1200
@@ -110,7 +110,7 @@
 #include "security/Session.h"
 namespace Security {
 bool CreateClientSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *) STUB_RETVAL(false)
-bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *) STUB_RETVAL(false)
+bool CreateServerSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, Security::PeerOptions &, const char *) STUB_RETVAL(false)
 void SessionSendGoodbye(const Security::SessionPointer &) STUB
 bool SessionIsResumed(const Security::SessionPointer &) STUB_RETVAL(false)
 void MaybeGetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &) STUB
diff -u -r -N squid-4.7/src/tests/stub_store_stats.cc squid-4.8/src/tests/stub_store_stats.cc
--- squid-4.7/src/tests/stub_store_stats.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/src/tests/stub_store_stats.cc	2019-07-10 07:05:20.000000000 +1200
@@ -14,8 +14,6 @@
 #include "StoreStats.h"
 #include <cstring>
 
-StoreInfoStats::StoreInfoStats() STUB
-
 StoreInfoStats &
 StoreInfoStats::operator +=(const StoreInfoStats &stats) STUB_RETVAL(*this)
 
diff -u -r -N squid-4.7/tools/cachemgr.cc squid-4.8/tools/cachemgr.cc
--- squid-4.7/tools/cachemgr.cc	2019-05-07 01:53:49.000000000 +1200
+++ squid-4.8/tools/cachemgr.cc	2019-07-10 07:05:20.000000000 +1200
@@ -355,7 +355,7 @@
 
     printf("<TR><TH ALIGN=\"left\">Manager name:</TH><TD><INPUT NAME=\"user_name\" ");
 
-    printf("size=\"30\" VALUE=\"%s\"></TD></TR>\n", user_name);
+    printf("size=\"30\" VALUE=\"%s\"></TD></TR>\n", rfc1738_escape(user_name));
 
     printf("<TR><TH ALIGN=\"left\">Password:</TH><TD><INPUT TYPE=\"password\" NAME=\"passwd\" ");
 
@@ -419,7 +419,7 @@
              script_name,
              req->hostname,
              req->port,
-             safe_str(req->user_name),
+             rfc1738_escape(safe_str(req->user_name)),
              action,
              safe_str(req->pub_auth));
     return url;
@@ -1074,8 +1074,8 @@
     const int bufLen = snprintf(buf, sizeof(buf), "%s|%d|%s|%s",
                                 req->hostname,
                                 (int) now,
-                                req->user_name ? req->user_name : "",
-                                req->passwd);
+                                rfc1738_escape(safe_str(req->user_name)),
+                                rfc1738_escape(req->passwd));
     debug("cmgr: pre-encoded for pub: %s\n", buf);
 
     const int encodedLen = base64_encode_len(bufLen);
@@ -1091,11 +1091,8 @@
 static void
 decode_pub_auth(cachemgr_request * req)
 {
-    char *buf;
     const char *host_name;
     const char *time_str;
-    const char *user_name;
-    const char *passwd;
 
     debug("cmgr: decoding pub: '%s'\n", safe_str(req->pub_auth));
     safe_free(req->passwd);
@@ -1103,16 +1100,17 @@
     if (!req->pub_auth || strlen(req->pub_auth) < 4 + strlen(safe_str(req->hostname)))
         return;
 
-    size_t decodedLen = BASE64_DECODE_LENGTH(strlen(req->pub_auth));
-    buf = (char*)xmalloc(decodedLen);
+    char *buf = static_cast<char*>(xmalloc(BASE64_DECODE_LENGTH(strlen(req->pub_auth))+1));
     struct base64_decode_ctx ctx;
     base64_decode_init(&ctx);
+    size_t decodedLen = 0;
     if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(buf), strlen(req->pub_auth), req->pub_auth) ||
             !base64_decode_final(&ctx)) {
         debug("cmgr: base64 decode failure. Incomplete auth token string.\n");
         xfree(buf);
         return;
     }
+    buf[decodedLen] = '\0';
 
     debug("cmgr: length ok\n");
 
@@ -1131,17 +1129,21 @@
 
     debug("cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now);
 
+    char *user_name;
     if ((user_name = strtok(NULL, "|")) == NULL) {
         xfree(buf);
         return;
     }
+    rfc1738_unescape(user_name);
 
     debug("cmgr: decoded uname: '%s'\n", user_name);
 
+    char *passwd;
     if ((passwd = strtok(NULL, "|")) == NULL) {
         xfree(buf);
         return;
     }
+    rfc1738_unescape(passwd);
 
     debug("cmgr: decoded passwd: '%s'\n", passwd);
 
diff -u -r -N squid-4.7/tools/helper-mux/helper-mux.8 squid-4.8/tools/helper-mux/helper-mux.8
--- squid-4.7/tools/helper-mux/helper-mux.8	2019-05-07 02:07:36.000000000 +1200
+++ squid-4.8/tools/helper-mux/helper-mux.8	2019-07-10 07:25:15.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "HELPER-MUX 8"
-.TH HELPER-MUX 8 "2019-05-06" "perl v5.28.1" "User Contributed Perl Documentation"
+.TH HELPER-MUX 8 "2019-07-09" "perl v5.28.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
