--- /dev/null
+From: http://bazaar.launchpad.net/~squid/squid/3-trunk/revision/13115
+
+Committer: Christos Tsantilas
+Date: 2013-11-07 10:46:14 UTC
+Revision ID: chtsanti@users.sourceforge.net-20131107104614-s3a9kzlkgm7x9rhf
+
+http://bugs.squid-cache.org/show_bug.cgi?id=3936
+Bug 3936: error-details.txt parse error
+
+Squid fails parsing error-details.txt template when one or more listed OpenSSL
+errors are not supported on running platform.
+This patch add a hardcoded list of OpenSSL errors wich can be optional.
+
+This is a Measurement Factory project
+
+=== modified file 'src/ssl/ErrorDetail.cc'
+--- src/ssl/ErrorDetail.cc 2013-07-31 00:13:04 +0000
++++ src/ssl/ErrorDetail.cc 2013-11-07 10:46:14 +0000
+@@ -221,6 +221,31 @@
+ {SSL_ERROR_NONE, NULL}
+ };
+
++static const char *OptionalSslErrors[] = {
++ "X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER",
++ "X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION",
++ "X509_V_ERR_KEYUSAGE_NO_CRL_SIGN",
++ "X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION",
++ "X509_V_ERR_INVALID_NON_CA",
++ "X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED",
++ "X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE",
++ "X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED",
++ "X509_V_ERR_INVALID_EXTENSION",
++ "X509_V_ERR_INVALID_POLICY_EXTENSION",
++ "X509_V_ERR_NO_EXPLICIT_POLICY",
++ "X509_V_ERR_DIFFERENT_CRL_SCOPE",
++ "X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE",
++ "X509_V_ERR_UNNESTED_RESOURCE",
++ "X509_V_ERR_PERMITTED_VIOLATION",
++ "X509_V_ERR_EXCLUDED_VIOLATION",
++ "X509_V_ERR_SUBTREE_MINMAX",
++ "X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE",
++ "X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX",
++ "X509_V_ERR_UNSUPPORTED_NAME_SYNTAX",
++ "X509_V_ERR_CRL_PATH_VALIDATION_ERROR",
++ NULL
++};
++
+ struct SslErrorAlias {
+ const char *name;
+ const Ssl::ssl_error_t *errors;
+@@ -331,6 +356,16 @@
+ return NULL;
+ }
+
++bool
++Ssl::ErrorIsOptional(const char *name)
++{
++ for (int i = 0; OptionalSslErrors[i] != NULL; ++i) {
++ if (strcmp(name, OptionalSslErrors[i]) == 0)
++ return true;
++ }
++ return false;
++}
++
+ const char *
+ Ssl::GetErrorDescr(Ssl::ssl_error_t value)
+ {
+
+=== modified file 'src/ssl/ErrorDetail.h'
+--- src/ssl/ErrorDetail.h 2013-05-30 10:10:29 +0000
++++ src/ssl/ErrorDetail.h 2013-11-07 10:46:14 +0000
+@@ -40,6 +40,14 @@
+
+ /**
+ \ingroup ServerProtocolSSLAPI
++ * Return true if the SSL error is optional and may not supported
++ * by current squid version
++ */
++
++bool ErrorIsOptional(const char *name);
++
++/**
++ \ingroup ServerProtocolSSLAPI
+ * Used to pass SSL error details to the error pages returned to the
+ * end user.
+ */
+
+=== modified file 'src/ssl/ErrorDetailManager.cc'
+--- src/ssl/ErrorDetailManager.cc 2013-10-25 00:13:46 +0000
++++ src/ssl/ErrorDetailManager.cc 2013-11-07 10:46:14 +0000
+@@ -218,32 +218,35 @@
+ }
+
+ Ssl::ssl_error_t ssl_error = Ssl::GetErrorCode(errorName.termedBuf());
+- if (ssl_error == SSL_ERROR_NONE) {
++ if (ssl_error != SSL_ERROR_NONE) {
++
++ if (theDetails->getErrorDetail(ssl_error)) {
++ debugs(83, DBG_IMPORTANT, HERE <<
++ "WARNING! duplicate entry: " << errorName);
++ return false;
++ }
++
++ ErrorDetailEntry &entry = theDetails->theList[ssl_error];
++ entry.error_no = ssl_error;
++ entry.name = errorName;
++ String tmp = parser.getByName("detail");
++ httpHeaderParseQuotedString(tmp.termedBuf(), tmp.size(), &entry.detail);
++ tmp = parser.getByName("descr");
++ httpHeaderParseQuotedString(tmp.termedBuf(), tmp.size(), &entry.descr);
++ bool parseOK = entry.descr.defined() && entry.detail.defined();
++
++ if (!parseOK) {
++ debugs(83, DBG_IMPORTANT, HERE <<
++ "WARNING! missing important field for detail error: " << errorName);
++ return false;
++ }
++
++ } else if (!Ssl::ErrorIsOptional(errorName.termedBuf())) {
+ debugs(83, DBG_IMPORTANT, HERE <<
+ "WARNING! invalid error detail name: " << errorName);
+ return false;
+ }
+
+- if (theDetails->getErrorDetail(ssl_error)) {
+- debugs(83, DBG_IMPORTANT, HERE <<
+- "WARNING! duplicate entry: " << errorName);
+- return false;
+- }
+-
+- ErrorDetailEntry &entry = theDetails->theList[ssl_error];
+- entry.error_no = ssl_error;
+- entry.name = errorName;
+- String tmp = parser.getByName("detail");
+- httpHeaderParseQuotedString(tmp.termedBuf(), tmp.size(), &entry.detail);
+- tmp = parser.getByName("descr");
+- httpHeaderParseQuotedString(tmp.termedBuf(), tmp.size(), &entry.descr);
+- bool parseOK = entry.descr.defined() && entry.detail.defined();
+-
+- if (!parseOK) {
+- debugs(83, DBG_IMPORTANT, HERE <<
+- "WARNING! missing imporant field for detail error: " << errorName);
+- return false;
+- }
+ }// else {only spaces and black lines; just ignore}
+
+ buf.consume(size);
+