=== modified file 'src/Makefile.am'
--- src/Makefile.am	2013-12-17 17:05:17 +0000
+++ src/Makefile.am	2013-12-19 10:45:53 +0000
@@ -23,7 +23,10 @@
 	SBuf.h \
 	SBuf.cc \
 	SBufExceptions.h \
-	SBufExceptions.cc
+	SBufExceptions.cc \
+	SquidString.h \
+	String.cc \
+	String.cci
 
 STOREMETA_SOURCE = \
 	StoreMeta.cc \
@@ -497,7 +500,6 @@
 	StatCounters.cc \
 	StatHist.h \
 	StatHist.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	stmem.cc \
@@ -589,8 +591,6 @@
 	MemBuf.h \
 	Store.cci \
 	StoreEntryStream.h \
-	String.cci \
-	SquidString.h \
 	SquidTime.h
 
 BUILT_SOURCES = \
@@ -728,11 +728,11 @@
 	MemBuf.cci \
 	MemBuf.h \
 	Parsing.h \
+	$(SBUF_SOURCE) \
 	store_key_md5.h \
 	store_key_md5.cc \
 	tests/stub_StoreMeta.cc \
 	StoreMetaUnpacker.cc \
-	String.cc \
 	SquidNew.cc \
 	tests/stub_time.cc \
 	ufsdump.cc \
@@ -1156,12 +1156,10 @@
 	Notes.cc \
 	Packer.cc \
 	Packer.h \
-	SquidString.h \
 	SquidTime.h \
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	log/access_log.h \
@@ -1268,7 +1266,6 @@
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
-	String.cc \
 	store_dir.cc \
 	StoreIOState.cc \
 	tests/stub_StoreMeta.cc \
@@ -1387,7 +1384,6 @@
 	HttpRequestMethod.cc \
 	Mem.h \
 	tests/stub_mem.cc \
-	String.cc \
 	tests/testCacheManager.cc \
 	tests/testCacheManager.h \
 	tests/testMain.cc \
@@ -1703,7 +1699,6 @@
 	store_swapmeta.cc \
 	repl_modules.h \
 	store.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	tests/stub_SwapDir.cc \
@@ -1975,7 +1970,6 @@
 	tests/stub_StoreMeta.cc \
 	StoreMetaUnpacker.cc \
 	StoreSwapLogData.cc \
-	String.cc \
 	tests/stub_SwapDir.cc \
 	tests/CapturingStoreEntry.h \
 	tests/testEvent.cc \
@@ -2220,7 +2214,6 @@
 	tests/stub_StoreMeta.cc \
 	StoreMetaUnpacker.cc \
 	StoreSwapLogData.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	tests/stub_SwapDir.cc \
@@ -2461,7 +2454,6 @@
 	tests/stub_StoreMeta.cc \
 	StoreMetaUnpacker.cc \
 	StoreSwapLogData.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	tests/stub_SwapDir.cc \
@@ -2538,7 +2530,6 @@
 	MemBuf.h \
 	Mem.h \
 	tests/stub_mem.cc \
-	String.cc \
 	cache_cf.h \
 	YesNoNone.h \
 	$(SBUF_SOURCE) \
@@ -2582,7 +2573,6 @@
 	HttpRequestMethod.cc \
 	Mem.h \
 	tests/stub_mem.cc \
-	String.cc \
 	tests/testHttpRequest.h \
 	tests/testHttpRequest.cc \
 	tests/testHttpRequestMethod.h \
@@ -2887,7 +2877,6 @@
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	SwapDir.cc \
@@ -2991,7 +2980,6 @@
 	Mem.h \
 	tests/stub_mem.cc \
 	MemBuf.cc \
-	String.cc \
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
@@ -3124,7 +3112,6 @@
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
-	String.cc \
 	tests/stub_debug.cc \
 	tests/stub_client_side_request.cc \
 	tests/stub_http.cc \
@@ -3305,7 +3292,6 @@
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	SwapDir.cc \
@@ -3561,7 +3547,6 @@
 	tests/stub_StoreMeta.cc \
 	StoreMetaUnpacker.cc \
 	StoreSwapLogData.cc \
-	String.cc \
 	StrList.h \
 	StrList.cc \
 	tests/stub_SwapDir.cc \
@@ -3657,8 +3642,6 @@
 	tests/stub_store.cc \
 	tests/stub_store_stats.cc \
 	tests/stub_tools.cc \
-	SquidString.h \
-	String.cc \
 	tests/stub_wordlist.cc \
 	tests/stub_MemBuf.cc
 nodist_tests_testSBuf_SOURCES=$(TESTSOURCES)
@@ -3697,7 +3680,6 @@
 	tests/stub_store_stats.cc \
 	tests/stub_tools.cc \
 	SquidString.h \
-	String.cc \
 	tests/stub_wordlist.cc \
 	tests/stub_MemBuf.cc
 nodist_tests_testSBufList_SOURCES=$(TESTSOURCES)
@@ -3723,7 +3705,6 @@
 	$(SBUF_SOURCE) \
 	SBufDetailedStats.h \
 	tests/stub_SBufDetailedStats.cc \
-	String.cc \
 	ConfigParser.cc \
 	fatal.h \
 	tests/stub_fatal.cc \
@@ -3763,7 +3744,6 @@
 	tests/stub_MemBuf.cc \
 	StatHist.cc \
 	StatHist.h \
-	String.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_comm.cc \
 	tests/stub_debug.cc \
@@ -3777,9 +3757,13 @@
 	tests/stub_pconn.cc \
 	tests/stub_stmem.cc \
 	repl_modules.h \
+	$(SBUF_SOURCE) \
+	SBufDetailedStats.h \
+	tests/stub_SBufDetailedStats.cc \
 	tests/stub_store.cc \
 	tests/stub_store_stats.cc \
 	tools.h \
+	tests/stub_time.cc \
 	tests/stub_tools.cc \
 	tests/testMain.cc \
 	tests/testStatHist.cc \

=== modified file 'src/SBuf.cc'
--- src/SBuf.cc	2013-12-18 17:53:43 +0000
+++ src/SBuf.cc	2013-12-19 07:56:42 +0000
@@ -117,16 +117,6 @@
     ++stats.live;
 }
 
-SBuf::SBuf(const String &S)
-        : store_(GetStorePrototype()), off_(0), len_(0)
-{
-    debugs(24, 8, id << " created from string");
-    assign(S.rawBuf(), S.size());
-    ++stats.alloc;
-    ++stats.allocFromString;
-    ++stats.live;
-}
-
 SBuf::SBuf(const std::string &s)
         : store_(GetStorePrototype()), off_(0), len_(0)
 {
@@ -758,7 +748,7 @@
     os <<
     "SBuf stats:\nnumber of allocations: " << alloc <<
     "\ncopy-allocations: " << allocCopy <<
-    "\ncopy-allocations from SquidString: " << allocFromString <<
+    "\ncopy-allocations from std::string: " << allocFromString <<
     "\ncopy-allocations from C String: " << allocFromCString <<
     "\nlive references: " << live <<
     "\nno-copy assignments: " << assignFast <<
@@ -825,15 +815,6 @@
         throw OutOfBoundsException(*this, pos, __FILE__, __LINE__);
 }
 
-String
-SBuf::toString() const
-{
-    String rv;
-    rv.limitInit(buf(), length());
-    ++stats.copyOut;
-    return rv;
-}
-
 /** re-allocate the backing store of the SBuf.
  *
  * If there are contents in the SBuf, they will be copied over.

=== modified file 'src/SBuf.h'
--- src/SBuf.h	2013-12-18 17:53:43 +0000
+++ src/SBuf.h	2013-12-19 07:56:42 +0000
@@ -32,7 +32,6 @@
 #include "base/InstanceId.h"
 #include "MemBlob.h"
 #include "SBufExceptions.h"
-#include "SquidString.h"
 
 #if HAVE_CLIMITS
 #include <climits>
@@ -134,12 +133,6 @@
      */
     explicit SBuf(const char *S, size_type n = npos);
 
-    /** Constructor: import SquidString, copying contents.
-     *
-     * This method will be removed once SquidString has gone.
-     */
-    explicit SBuf(const String &S);
-
     /// Constructor: import std::string. Contents are copied.
     explicit SBuf(const std::string &s);
 
@@ -313,7 +306,7 @@
     /** exports a pointer to the SBuf internal storage.
      * \warning ACCESSING RAW STORAGE IS DANGEROUS!
      *
-     * Returns a ead-only pointer to SBuf's content. No terminating null
+     * Returns a read-only pointer to SBuf's content. No terminating null
      * character is appended (use c_str() for that).
      * The returned value points to an internal location whose contents
      * are guaranteed to remain unchanged only until the next call
@@ -551,12 +544,6 @@
      */
     SBuf toUpper() const;
 
-    /** String export function
-     * converts the SBuf to a legacy String, by copy.
-     * \deprecated
-     */
-    String toString() const;
-
     /// std::string export function
     std::string toStdString() const { return std::string(buf(),length()); }
 

=== modified file 'src/Server.cc'
--- src/Server.cc	2013-12-19 00:55:46 +0000
+++ src/Server.cc	2013-12-19 07:56:42 +0000
@@ -478,7 +478,7 @@
 
     absUrl = NULL;
     hdrUrl = rep->header.getStr(hdr);
-    if (hdrUrl == NULL) {
+    if (!hdrUrl || !*hdrUrl) {
         return;
     }
 

=== modified file 'src/SquidString.h'
--- src/SquidString.h	2013-12-20 05:55:43 +0000
+++ src/SquidString.h	2013-12-19 08:06:39 +0000
@@ -33,6 +33,8 @@
 #ifndef SQUID_STRING_H
 #define SQUID_STRING_H
 
+#include "SBuf.h"
+
 #if HAVE_OSTREAM
 #include <ostream>
 #endif
@@ -50,15 +52,24 @@
     _SQUID_INLINE_ String();
     String(char const *);
     String(String const &);
-    ~String();
-
-    typedef size_t size_type; //storage size intentionally unspecified
-    const static size_type npos = static_cast<size_type>(-1);
+
+    explicit String(SBuf const &s) : buf_(s), defined_(s.length() > 0) {}
+    SBuf &toSBuf() const {return buf_;}
+
+    typedef SBuf::size_type size_type; //storage size intentionally unspecified
+    const static size_type npos = SBuf::npos;
 
     String &operator =(char const *);
     String &operator =(String const &);
+    String &operator =(SBuf const &s) {
+        defined_=(s.length() > 0); // SBuf is always defined; estimating
+        buf_=s;
+        return *this;
+    }
     bool operator ==(String const &) const;
+    // {return defined() == s.defined() && buf_ == s.buf_;}
     bool operator !=(String const &) const;
+    // {return defined() != s.defined() || buf_ != s.buf_;}
 
     /**
      * Retrieve a single character in the string.
@@ -109,25 +120,18 @@
     _SQUID_INLINE_ void cut(size_type newLength);
 
 private:
-    void allocAndFill(const char *str, int len);
-    void allocBuffer(size_type sz);
-    void setBuffer(char *buf, size_type sz);
-
-    bool defined() const {return buf_!=NULL;}
-    bool undefined() const {return !defined();}
+    bool defined() const {return defined_;}
 
     _SQUID_INLINE_ bool nilCmp(bool, bool, int &) const;
 
-    /* never reference these directly! */
-    size_type size_; /* buffer size; 64K limit */
-
-    size_type len_;  /* current length  */
-
-    char *buf_;
-
-    _SQUID_INLINE_ void set(char const *loc, char const ch);
-    _SQUID_INLINE_ void cutPointer(char const *loc);
-
+    mutable SBuf buf_;
+
+    // SquidString used to track whether buf_ was NULL or not
+    // and some code makes use of this property.
+    // Until that is all checked and defined()/undefined() erased
+    // we explicitly track whether SquidString would have had
+    // buf_ allocated.
+    mutable bool defined_;
 };
 
 _SQUID_INLINE_ std::ostream & operator<<(std::ostream& os, String const &aString);

=== modified file 'src/StrList.cc'
--- src/StrList.cc	2012-08-29 09:34:34 +0000
+++ src/StrList.cc	2013-12-10 12:34:23 +0000
@@ -113,7 +113,7 @@
     if (!*pos) {
         *pos = str->termedBuf();
 
-        if (!*pos)
+        if (!*pos || !**pos)
             return 0;
     }
 

=== modified file 'src/String.cc'
--- src/String.cc	2012-10-04 09:14:06 +0000
+++ src/String.cc	2013-11-21 10:31:43 +0000
@@ -37,6 +37,7 @@
 #include "mgr/Registration.h"
 #include "profiler/Profiler.h"
 #include "Store.h"
+#include "SquidString.h"
 
 #if HAVE_LIMITS_H
 #include <limits.h>
@@ -49,37 +50,10 @@
     return size();
 }
 
-// low-level buffer allocation,
-// does not free old buffer and does not adjust or look at len_
-void
-String::allocBuffer(String::size_type sz)
-{
-    PROF_start(StringInitBuf);
-    assert (undefined());
-    char *newBuffer = (char*)memAllocString(sz, &sz);
-    setBuffer(newBuffer, sz);
-    PROF_stop(StringInitBuf);
-}
-
-// low-level buffer assignment
-// does not free old buffer and does not adjust or look at len_
-void
-String::setBuffer(char *aBuf, String::size_type aSize)
-{
-    assert(undefined());
-    assert(aSize < 65536);
-    buf_ = aBuf;
-    size_ = aSize;
-}
-
-String::String(char const *aString) : size_(0), len_(0), buf_(NULL)
-{
-    if (aString)
-        allocAndFill(aString, strlen(aString));
-#if DEBUGSTRINGS
-
-    StringRegistry::Instance().add(this);
-#endif
+String::String(char const *aString) :
+        buf_(aString),
+        defined_(aString != NULL)
+{
 }
 
 String &
@@ -92,9 +66,8 @@
 String &
 String::operator =(String const &old)
 {
-    clean(); // TODO: optimize to avoid cleaning the buffer we can use
-    if (old.size() > 0)
-        allocAndFill(old.rawBuf(), old.size());
+    buf_ = old.buf_;
+    defined_ = old.defined_;
     return *this;
 }
 
@@ -121,31 +94,11 @@
 String::limitInit(const char *str, int len)
 {
     clean(); // TODO: optimize to avoid cleaning the buffer we can use
-    allocAndFill(str, len);
-}
-
-// Allocates the buffer to fit the supplied string and fills it.
-// Does not clean.
-void
-String::allocAndFill(const char *str, int len)
-{
-    PROF_start(StringAllocAndFill);
-    assert(this && str);
-    allocBuffer(len + 1);
-    len_ = len;
-    memcpy(buf_, str, len);
-    buf_[len] = '\0';
-    PROF_stop(StringAllocAndFill);
-}
-
-String::String(String const &old) : size_(0), len_(0), buf_(NULL)
-{
-    if (old.size() > 0)
-        allocAndFill(old.rawBuf(), old.size());
-#if DEBUGSTRINGS
-
-    StringRegistry::Instance().add(this);
-#endif
+    append(str, len);
+}
+
+String::String(String const &old) : buf_(old.buf_), defined_(old.defined_)
+{
 }
 
 void
@@ -154,34 +107,23 @@
     PROF_start(StringClean);
     assert(this);
 
-    /* TODO if mempools has already closed this will FAIL!! */
-    if (defined())
-        memFreeString(size_, buf_);
-
-    len_ = 0;
-
-    size_ = 0;
-
-    buf_ = NULL;
+    buf_.clear();
+    defined_=false;
+
     PROF_stop(StringClean);
 }
 
-String::~String()
-{
-    clean();
-#if DEBUGSTRINGS
-
-    StringRegistry::Instance().remove(this);
-#endif
-}
-
 void
 String::reset(char const *str)
 {
     PROF_start(StringReset);
     clean(); // TODO: optimize to avoid cleaning the buffer if we can reuse it
-    if (str)
-        allocAndFill(str, strlen(str));
+    if (str) {
+        append(str);
+        // XXX: empty string "" sent to append means no change,
+        // but on reset / assignment it means set a defined empty string.
+        defined_=true;
+    }
     PROF_stop(StringReset);
 }
 
@@ -192,26 +134,8 @@
     assert(str && len >= 0);
 
     PROF_start(StringAppend);
-    if (len_ + len < size_) {
-        strncat(buf_, str, len);
-        len_ += len;
-    } else {
-        // Create a temporary string and absorb it later.
-        String snew;
-        assert(len_ + len < 65536); // otherwise snew.len_ overflows below
-        snew.len_ = len_ + len;
-        snew.allocBuffer(snew.len_ + 1);
-
-        if (len_)
-            memcpy(snew.buf_, rawBuf(), len_);
-
-        if (len)
-            memcpy(snew.buf_ + len_, str, len);
-
-        snew.buf_[snew.len_] = '\0';
-
-        absorb(snew);
-    }
+    buf_.append(str, len);
+    defined_ = true;
     PROF_stop(StringAppend);
 }
 
@@ -234,31 +158,24 @@
 void
 String::append(String const &old)
 {
-    append(old.rawBuf(), old.len_);
+    append(old.rawBuf(), old.size());
 }
 
 void
 String::absorb(String &old)
 {
-    clean();
-    setBuffer(old.buf_, old.size_);
-    len_ = old.len_;
-    old.size_ = 0;
-    old.buf_ = NULL;
-    old.len_ = 0;
+    operator = (old);
+    old.clean();
 }
 
 String
 String::substr(String::size_type from, String::size_type to) const
 {
-//    Must(from >= 0 && from < size());
     Must(from < size());
     Must(to > 0 && to <= size());
     Must(to > from);
 
-    String rv;
-    rv.limitInit(rawBuf()+from,to-from);
-    return rv;
+    return String(buf_.substr(from, to-from));
 }
 
 #if DEBUGSTRINGS
@@ -442,7 +359,7 @@
 const char *
 String::pos(char const *aString) const
 {
-    if (undefined())
+    if (!defined())
         return NULL;
     return strstr(termedBuf(), aString);
 }
@@ -450,7 +367,7 @@
 const char *
 String::pos(char const ch) const
 {
-    if (undefined())
+    if (!defined())
         return NULL;
     return strchr(termedBuf(), ch);
 }
@@ -458,7 +375,7 @@
 const char *
 String::rpos(char const ch) const
 {
-    if (undefined())
+    if (!defined())
         return NULL;
     return strrchr(termedBuf(), (ch));
 }

=== modified file 'src/String.cci'
--- src/String.cci	2013-11-23 00:58:42 +0000
+++ src/String.cci	2013-12-11 05:56:46 +0000
@@ -40,35 +40,36 @@
 #endif /* INT_MAX */
 #endif /* HAVE_STDINT_H */
 
-String::String() : size_(0), len_(0), buf_(NULL)
+String::String() : buf_(), defined_(false)
 {
-#if DEBUGSTRINGS
-    StringRegistry::Instance().add(this);
-#endif
 }
 
 String::size_type
 String::size() const
 {
-    return len_;
+    return buf_.length();
 }
 
 char const *
 String::rawBuf() const
 {
-    return buf_;
+    return termedBuf();
 }
 
 char const *
 String::termedBuf() const
 {
-    return buf_;
+    // XXX: callers will probably try and write to the buffer,
+    // but SquidString never offered any more guarantee than SBuf
+    // does now about buffers existence.
+    // (this used to return NULL result on undefined)
+    return buf_.c_str();
 }
 
 char
 String::operator [](unsigned int aPos) const
 {
-    assert(aPos < size_);
+    assert(aPos < size());
 
     return buf_[aPos];
 }
@@ -94,11 +95,7 @@
 int
 String::cmp(char const *aString) const
 {
-    int result = 0;
-    if (nilCmp(!size(), (!aString || !*aString), result))
-        return result;
-
-    return strcmp(termedBuf(), aString);
+    return buf_.cmp(SBuf(aString));
 }
 
 int
@@ -114,21 +111,13 @@
 int
 String::cmp(String const &aString) const
 {
-    int result = 0;
-    if (nilCmp(!size(), !aString.size(), result))
-        return result;
-
-    return strcmp(termedBuf(), aString.termedBuf());
+    return buf_.cmp(aString.buf_);
 }
 
 int
 String::caseCmp(char const *aString) const
 {
-    int result = 0;
-    if (nilCmp(!size(), (!aString || !*aString), result))
-        return result;
-
-    return strcasecmp(termedBuf(), aString);
+    return buf_.caseCmp(SBuf(aString));
 }
 
 int
@@ -144,44 +133,27 @@
 int
 String::caseCmp(const String &str) const
 {
-    return caseCmp(str.rawBuf(),str.size());
-}
-
-void
-String::set(char const *loc, char const ch)
-{
-    if (loc < buf_ || loc > (buf_ + size_) ) return;
-
-    buf_[loc-buf_] = ch;
+    return buf_.caseCmp(str.buf_);
 }
 
 void
 String::cut(String::size_type newLength)
 {
     // size_type is size_t, unsigned. No need to check for newLength <0
-    if (newLength > len_) return;
+    if (newLength > buf_.length()) return;
 
-    len_ = newLength;
+    buf_ = buf_.substr(0, newLength);
 
     // buf_ may be NULL on zero-length strings.
-    if (len_ == 0 && buf_ == NULL) return;
-
-    buf_[newLength] = '\0';
-}
-
-void
-String::cutPointer(char const *loc)
-{
-    if (loc < buf_ || loc > (buf_ + size_) ) return;
-
-    len_ = loc-buf_;
-    buf_[len_] = '\0';
+    if (buf_.length() == 0 && !defined()) return;
+
+    buf_.setAt(newLength, '\0'); // terminate String.
 }
 
 std::ostream &
 operator<<(std::ostream& os, String const &aString)
 {
-    os.write(aString.rawBuf(),aString.size());
+    os << aString.toSBuf();
     return os;
 }
 

=== modified file 'src/acl/HttpHeaderData.cc'
--- src/acl/HttpHeaderData.cc	2013-11-21 13:05:47 +0000
+++ src/acl/HttpHeaderData.cc	2013-12-19 08:07:16 +0000
@@ -76,8 +76,7 @@
             return false;
     }
 
-    SBuf cvalue(value);
-    return regex_rule->match(cvalue.c_str());
+    return regex_rule->match(value.termedBuf());
 }
 
 wordlist *

=== modified file 'src/acl/ReplyHeaderStrategy.h'
--- src/acl/ReplyHeaderStrategy.h	2013-10-25 00:13:46 +0000
+++ src/acl/ReplyHeaderStrategy.h	2013-12-11 05:29:21 +0000
@@ -67,7 +67,7 @@
 {
     char const *theHeader = checklist->reply->header.getStr(header);
 
-    if (NULL == theHeader)
+    if (!theHeader || !*theHeader)
         return 0;
 
     return data->match(theHeader);

=== modified file 'src/acl/RequestHeaderStrategy.h'
--- src/acl/RequestHeaderStrategy.h	2013-10-25 00:13:46 +0000
+++ src/acl/RequestHeaderStrategy.h	2013-12-11 05:29:38 +0000
@@ -67,7 +67,7 @@
 {
     char const *theHeader = checklist->request->header.getStr(header);
 
-    if (NULL == theHeader)
+    if (!theHeader || !*theHeader)
         return 0;
 
     return data->match(theHeader);

=== modified file 'src/adaptation/Iterator.cc'
--- src/adaptation/Iterator.cc	2013-12-05 11:04:45 +0000
+++ src/adaptation/Iterator.cc	2013-12-19 07:56:42 +0000
@@ -56,7 +56,7 @@
             request = theCause;
         Must(request);
         Adaptation::History::Pointer ah = request->adaptHistory(true);
-        SBuf gid(theGroup->id);
+        SBuf gid(theGroup->id.toSBuf());
         ah->recordAdaptationService(gid);
     }
 
@@ -96,7 +96,7 @@
 
     if (Adaptation::Config::needHistory) {
         Adaptation::History::Pointer ah = request->adaptHistory(true);
-        SBuf uid(thePlan.current()->cfg().key);
+        SBuf uid(thePlan.current()->cfg().key.toSBuf());
         ah->recordAdaptationService(uid);
     }
 

=== modified file 'src/adaptation/ecap/ServiceRep.cc'
--- src/adaptation/ecap/ServiceRep.cc	2013-12-05 11:04:45 +0000
+++ src/adaptation/ecap/ServiceRep.cc	2013-12-19 07:56:42 +0000
@@ -235,7 +235,7 @@
 bool Adaptation::Ecap::ServiceRep::wantsUrl(const String &urlPath) const
 {
     Must(up());
-    return theService->wantsUrl(urlPath.termedBuf());
+    return theService->wantsUrl(urlPath);
 }
 
 Adaptation::Initiate *

=== modified file 'src/auth/UserRequest.cc'
--- src/auth/UserRequest.cc	2013-12-06 14:59:47 +0000
+++ src/auth/UserRequest.cc	2013-12-19 07:56:42 +0000
@@ -302,6 +302,10 @@
 
     proxy_auth = request->header.getStr(headertype);
 
+    // handle empty string results
+    if (!*proxy_auth)
+        proxy_auth = NULL;
+
     /*
      * a note on proxy_auth logix here:
      * proxy_auth==NULL -> unauthenticated request || already

=== modified file 'src/auth/digest/UserRequest.cc'
--- src/auth/digest/UserRequest.cc	2013-12-06 14:59:47 +0000
+++ src/auth/digest/UserRequest.cc	2013-12-19 07:56:42 +0000
@@ -146,7 +146,7 @@
                 if (last_broken_addr != request->client_addr) {
                     debugs(29, DBG_IMPORTANT, "Digest POST bug detected from " <<
                            request->client_addr << " using '" <<
-                           (useragent ? useragent : "-") <<
+                           (useragent && *useragent ? useragent : "-") <<
                            "'. Please upgrade browser. See Bug #630 for details.");
 
                     last_broken_addr = request->client_addr;

=== modified file 'src/cache_manager.cc'
--- src/cache_manager.cc	2013-10-25 00:13:46 +0000
+++ src/cache_manager.cc	2013-12-11 03:56:15 +0000
@@ -148,7 +148,7 @@
 Mgr::Action::Pointer
 CacheManager::createNamedAction(const char *actionName)
 {
-    Must(actionName);
+    Must(actionName && *actionName);
 
     Mgr::Command::Pointer cmd = new Mgr::Command;
     cmd->profile = findAction(actionName);

=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc	2013-12-06 14:59:47 +0000
+++ src/client_side_request.cc	2013-12-19 07:56:42 +0000
@@ -604,7 +604,7 @@
     // Require a Host: header.
     const char *host = http->request->header.getStr(HDR_HOST);
 
-    if (!host) {
+    if (!host || !*host) {
         // TODO: dump out the HTTP/1.1 error about missing host header.
         // otherwise this is fine, can't forge a header value when its not even set.
         debugs(85, 3, HERE << "validate skipped with no Host: header present.");
@@ -1064,7 +1064,6 @@
     HttpRequest *request = http->request;
     HttpHeader *req_hdr = &request->header;
     bool no_cache = false;
-    const char *str;
 
     request->imslen = -1;
     request->ims = req_hdr->getTime(HDR_IF_MODIFIED_SINCE);
@@ -1090,7 +1089,8 @@
         */
         if (Config.onoff.ie_refresh) {
             if (http->flags.accel && request->flags.ims) {
-                if ((str = req_hdr->getStr(HDR_USER_AGENT))) {
+                const char *str = req_hdr->getStr(HDR_USER_AGENT);
+                if (str && *str) {
                     if (strstr(str, "MSIE 5.01") != NULL)
                         no_cache=true;
                     else if (strstr(str, "MSIE 5.0") != NULL)

=== modified file 'src/esi/VarState.cc'
--- src/esi/VarState.cc	2012-11-19 11:29:31 +0000
+++ src/esi/VarState.cc	2013-12-11 05:42:34 +0000
@@ -409,7 +409,7 @@
 ESIVariableUserAgent::esiUserOs_t
 ESIVariableUserAgent::identifyOs(char const *s) const
 {
-    if (!s)
+    if (!s || !*s)
         return ESI_OS_OTHER;
 
     if (strstr (s, "Windows"))

=== modified file 'src/http.cc'
--- src/http.cc	2013-11-23 05:21:34 +0000
+++ src/http.cc	2013-12-19 07:56:42 +0000
@@ -451,7 +451,7 @@
      * continuous push replies.  These are generally dynamic and
      * probably should not be cachable
      */
-    if ((v = hdr->getStr(HDR_CONTENT_TYPE)))
+    if ((v = hdr->getStr(HDR_CONTENT_TYPE)) && *v)
         if (!strncasecmp(v, "multipart/x-mixed-replace", 25)) {
             debugs(22, 3, HERE << "NO because Content-Type:multipart/x-mixed-replace");
             return 0;
@@ -591,7 +591,6 @@
     String vary, hdr;
     const char *pos = NULL;
     const char *item;
-    const char *value;
     int ilen;
     static String vstr;
 
@@ -613,10 +612,9 @@
         strListAdd(&vstr, name, ',');
         hdr = request->header.getByName(name);
         safe_free(name);
-        value = hdr.termedBuf();
 
-        if (value) {
-            value = rfc1738_escape_part(value);
+        if (hdr.size()) {
+            const char *value = rfc1738_escape_part(hdr.termedBuf());
             vstr.append("=\"", 2);
             vstr.append(value);
             vstr.append("\"", 1);
@@ -638,10 +636,9 @@
         strListAdd(&vstr, name, ',');
         hdr = request->header.getByName(name);
         safe_free(name);
-        value = hdr.termedBuf();
 
-        if (value) {
-            value = rfc1738_escape_part(value);
+        if (hdr.size()) {
+            const char *value = rfc1738_escape_part(hdr.termedBuf());
             vstr.append("=\"", 2);
             vstr.append(value);
             vstr.append("\"", 1);
@@ -654,7 +651,7 @@
 #endif
 
     debugs(11, 3, "httpMakeVaryMark: " << vstr);
-    return vstr.termedBuf();
+    return vstr.size() ? vstr.termedBuf() : NULL;
 }
 
 void

=== modified file 'src/redirect.cc'
--- src/redirect.cc	2013-11-23 00:58:42 +0000
+++ src/redirect.cc	2013-12-10 12:46:54 +0000
@@ -260,7 +260,7 @@
 #endif
 
     if (!r->client_ident && http->request->extacl_user.size() > 0) {
-        r->client_ident = http->request->extacl_user.termedBuf();
+        r->client_ident = (http->request->extacl_user.size() ? http->request->extacl_user.termedBuf() : NULL);
         debugs(61, 5, HERE << "acl-user=" << (r->client_ident?r->client_ident:"NULL"));
     }
 

=== modified file 'src/ssl/ErrorDetail.cc'
--- src/ssl/ErrorDetail.cc	2013-11-23 00:58:42 +0000
+++ src/ssl/ErrorDetail.cc	2013-12-02 09:59:30 +0000
@@ -473,7 +473,7 @@
     static char tmpBuffer[64];
     // We can use the GetErrorName but using the detailEntry is faster,
     // so try it first.
-    const char *err = detailEntry.name.termedBuf();
+    const char *err = (detailEntry.name.size() ? detailEntry.name.termedBuf() : NULL);
 
     // error details not loaded yet or not defined in error_details.txt,
     // try the GetErrorName...
@@ -494,8 +494,8 @@
 {
     if (error_no == SSL_ERROR_NONE)
         return "[No Error]";
-    if (const char *err = detailEntry.descr.termedBuf())
-        return err;
+    if (detailEntry.descr.size() > 0)
+        return detailEntry.descr.termedBuf();
     return "[Not available]";
 }
 
@@ -554,7 +554,7 @@
     int code_len = 0;
 
     if (ErrorDetailsManager::GetInstance().getErrorDetail(error_no, request, detailEntry))
-        s = detailEntry.detail.termedBuf();
+        s = (detailEntry.detail.size() ? detailEntry.detail.termedBuf() : NULL);
 
     if (!s)
         s = SslErrorDetailDefaultStr;

=== modified file 'src/ssl/ErrorDetailManager.cc'
--- src/ssl/ErrorDetailManager.cc	2013-11-23 05:21:34 +0000
+++ src/ssl/ErrorDetailManager.cc	2013-12-19 07:56:42 +0000
@@ -133,7 +133,7 @@
             errDetails = new ErrorDetailsList();
             ErrorDetailFile detailTmpl(errDetails);
             if (detailTmpl.loadFor(request.getRaw())) {
-                if (detailTmpl.language()) {
+                if (detailTmpl.language() && *detailTmpl.language() != '\0') {
                     debugs(83, 8, HERE << "Found details on disk for language " << detailTmpl.language());
                     errDetails->errLanguage = detailTmpl.language();
                     cacheDetails(errDetails);

=== modified file 'src/tests/testSBuf.cc'
--- src/tests/testSBuf.cc	2013-12-18 17:53:43 +0000
+++ src/tests/testSBuf.cc	2013-12-19 07:56:42 +0000
@@ -106,13 +106,6 @@
         CPPUNIT_ASSERT_EQUAL(s4,s3);
     }
 
-    // TEST: go via SquidString adapters.
-    {
-        String str(fox);
-        SBuf s1(str);
-        CPPUNIT_ASSERT_EQUAL(literal,s1);
-    }
-
     // TEST: go via std::string adapter.
     {
         std::string str(fox);

=== modified file 'src/tests/testString.cc'
--- src/tests/testString.cc	2013-10-25 00:13:46 +0000
+++ src/tests/testString.cc	2013-11-20 22:04:34 +0000
@@ -37,13 +37,13 @@
     String left("");
     String right;
     /* an empty string ("") is equal to a default string */
-    CPPUNIT_ASSERT(!left.cmp(right));
-    CPPUNIT_ASSERT(!left.cmp(NULL));
-    CPPUNIT_ASSERT(!left.cmp(NULL, 1));
+    CPPUNIT_ASSERT_EQUAL(0,left.cmp(right));
+    CPPUNIT_ASSERT_EQUAL(0,left.cmp(NULL));
+    CPPUNIT_ASSERT_EQUAL(0,left.cmp(NULL, 1));
     /* reverse the order to catch corners */
-    CPPUNIT_ASSERT(!right.cmp(left));
-    CPPUNIT_ASSERT(!right.cmp(""));
-    CPPUNIT_ASSERT(!right.cmp("", 1));
+    CPPUNIT_ASSERT_EQUAL(0,right.cmp(left));
+    CPPUNIT_ASSERT_EQUAL(0,right.cmp(""));
+    CPPUNIT_ASSERT_EQUAL(0,right.cmp("", 1));
 }
 
 void


