]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Improved checks on SBuf::*Size methods
authorFrancesco Chemolli <kinkie@squid-cache.org>
Thu, 1 Aug 2013 09:07:53 +0000 (11:07 +0200)
committerFrancesco Chemolli <kinkie@squid-cache.org>
Thu, 1 Aug 2013 09:07:53 +0000 (11:07 +0200)
Improved detection of vsnprintf's not-well-defined behavior.

src/SBuf.cc
src/SBuf.h

index 933634652cf5da87da9a4f3fdf28b32e1b62175c..48050976548152b22ac42ea1c78e36adc604f04b 100644 (file)
@@ -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_;
     }
index 6e64aa988ac693d87243327a5fa3d8cbe3ea0534..0752223851ef8148fd5140b75d3fe2383d54fdb7 100644 (file)
@@ -418,7 +418,7 @@ public:
      */
     void reserveSpace(size_type minSpace) {
         Must(0 <= minSpace);
-        Must(minSpace <= maxSize);
+        Must(length() <= maxSize - minSpace);
         reserveCapacity(length()+minSpace);
     }