From: Francesco Chemolli Date: Thu, 1 Aug 2013 09:07:53 +0000 (+0200) Subject: Improved checks on SBuf::*Size methods X-Git-Tag: SQUID_3_5_0_1~612^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a44b8b80ac439c0a5817c7e19858074494ecb3ed;p=thirdparty%2Fsquid.git Improved checks on SBuf::*Size methods Improved detection of vsnprintf's not-well-defined behavior. --- diff --git a/src/SBuf.cc b/src/SBuf.cc index 933634652c..4805097654 100644 --- a/src/SBuf.cc +++ b/src/SBuf.cc @@ -192,7 +192,7 @@ char * SBuf::rawSpace(size_type minSpace) { Must(0 <= minSpace); - Must(minSpace <= maxSize); + Must(length() <= maxSize - minSpace); debugs(24, 7, "reserving " << minSpace << " for " << id); ++stats.rawAccess; // we're not concerned about RefCounts here, @@ -303,12 +303,18 @@ SBuf::vappendf(const char *fmt, va_list vargs) // data was appended, update internal state len_ += sz; - // TODO: this does NOT belong here, but to class-init or autoconf + /* C99 specifies that the final '\0' is not counted in vsnprintf's * return value. Older compilers/libraries might instead count it */ /* check whether '\0' was appended and counted */ - - if (at(len_-1) == '\0') { + static bool snPrintfTerminatorChecked = false, + snPrintfTerminatorCounted = false; + if (!snPrintfTerminatorChecked) { + char testbuf[16]; + snPrintfTerminatorCounted = snprintf(testbuf, sizeof(testbuf), + "%s", "1") == 2; + } + if (snPrintfTerminatorCounted) { --sz; --len_; } diff --git a/src/SBuf.h b/src/SBuf.h index 6e64aa988a..0752223851 100644 --- a/src/SBuf.h +++ b/src/SBuf.h @@ -418,7 +418,7 @@ public: */ void reserveSpace(size_type minSpace) { Must(0 <= minSpace); - Must(minSpace <= maxSize); + Must(length() <= maxSize - minSpace); reserveCapacity(length()+minSpace); }