Fixed "Source and destination overlap in memcpy" Valgrind errors.

Before this patch, source and destination arguments in
log_quoted_string() could point to the same static memory area, causing
multiple Valgrind-reported errors. Fixed by creating another buffer for
storing the quoted-processed output string. The buffer size should be
enough to hold all processed escape sequences.


Regards,
Eduard.

Fixed "Source and destination overlap in memcpy" Valgrind errors.

Before this patch, source and destination arguments in
log_quoted_string() could point to the same static memory area, causing
multiple Valgrind-reported errors. Fixed by creating another buffer to
store quoted-processed output string.

=== modified file 'src/format/Format.cc'
--- src/format/Format.cc	2017-01-01 00:12:22 +0000
+++ src/format/Format.cc	2017-01-15 15:24:28 +0000
@@ -1440,76 +1440,81 @@
 
         case LFT_EXT_ACL_DATA:
             if (!al->lastAclData.isEmpty())
                 out = al->lastAclData.c_str();
             break;
         }
 
         if (dooff) {
             snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff);
             out = tmp;
 
         } else if (doint) {
             snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint);
             out = tmp;
         } else if (doMsec) {
             if (fmt->widthMax < 0) {
                 snprintf(tmp, sizeof(tmp), "%0*ld", fmt->widthMin , tvToMsec(outtv));
             } else {
                 int precision = fmt->widthMax;
                 snprintf(tmp, sizeof(tmp), "%0*" PRId64 ".%0*" PRId64 "", fmt->zero && (fmt->widthMin - precision - 1 >= 0) ? fmt->widthMin - precision - 1 : 0, static_cast<int64_t>(outtv.tv_sec * 1000 + outtv.tv_usec / 1000), precision, static_cast<int64_t>((outtv.tv_usec % 1000 )* (1000 / fmt->divisor)));
             }
             out = tmp;
         } else if (doSec) {
             int precision = fmt->widthMax >=0 ? fmt->widthMax :3;
             snprintf(tmp, sizeof(tmp), "%0*" PRId64 ".%0*d", fmt->zero && (fmt->widthMin - precision - 1 >= 0) ? fmt->widthMin - precision - 1 : 0, static_cast<int64_t>(outtv.tv_sec), precision, (int)(outtv.tv_usec / fmt->divisor));
             out = tmp;
         }
 
         if (out && *out) {
             if (quote || fmt->quote != LOG_QUOTE_NONE) {
+                // Do not write to the tmp buffer because it may contain the to-be-quoted value.
+                static char quotedOut[2 * sizeof(tmp)];
+                static_assert(sizeof(quotedOut) > 0, "quotedOut has zero length");
+                quotedOut[0] = '\0';
+
                 char *newout = NULL;
                 int newfree = 0;
 
                 switch (fmt->quote) {
 
                 case LOG_QUOTE_NONE:
                     newout = rfc1738_escape_unescaped(out);
                     break;
 
                 case LOG_QUOTE_QUOTES: {
                     size_t out_len = static_cast<size_t>(strlen(out)) * 2 + 1;
                     if (out_len >= sizeof(tmp)) {
                         newout = (char *)xmalloc(out_len);
                         newfree = 1;
                     } else
-                        newout = tmp;
+                        newout = quotedOut;
                     log_quoted_string(out, newout);
                 }
                 break;
 
                 case LOG_QUOTE_MIMEBLOB:
                     newout = QuoteMimeBlob(out);
                     newfree = 1;
                     break;
 
                 case LOG_QUOTE_URL:
                     newout = rfc1738_escape(out);
                     break;
 
                 case LOG_QUOTE_SHELL: {
                     MemBuf mbq;
                     mbq.init();
                     strwordquote(&mbq, out);
                     newout = mbq.content();
                     mbq.stolen = 1;
                     newfree = 1;
                 }
                 break;
 
                 case LOG_QUOTE_RAW:
                     break;
                 }
 
                 if (newout) {
                     if (dofree)
                         safe_free(out);

_______________________________________________
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to