SBuf::assign(const char *S, size_type n)
{
debugs(24, 6, id << " from c-string, n=" << n << ")");
+ Locker prevent_raw_memory_madness(this, S, n);
clear();
return append(S, n); //bounds checked in append()
}
SBuf&
SBuf::append(const SBuf &S)
{
+ Locker prevent_raw_memory_madness(this, S.buf(), S.length());
return lowAppend(S.buf(), S.length());
}
if (Ssize == SBuf::npos)
Ssize = strlen(S);
debugs(24, 7, "from c-string to id " << id);
+ Locker prevent_raw_memory_madness(this, S, Ssize);
// coverity[access_dbuff_in_call]
return lowAppend(S, Ssize);
}
SBuf&
SBuf::Printf(const char *fmt, ...)
{
+ // with printf() an arg might be a dangerous char*
+ // NP: cant rely on vappendf() Locker because of clear()
+ Locker prevent_raw_memory_madness(this, buf(), length());
+
va_list args;
va_start(args, fmt);
clear();
//reserve twice the format-string size, it's a likely heuristic
size_type requiredSpaceEstimate = strlen(fmt)*2;
+ // with appendf() an arg might be a dangerous char*
+ Locker prevent_raw_memory_madness(this, buf(), length());
+
char *space = rawSpace(requiredSpaceEstimate);
#ifdef VA_COPY
va_list ap;
// TODO: possibly implement a replace() call
private:
+ class Locker
+ {
+ public:
+ Locker(SBuf *parent, const char *Q, size_t len) : locket(nullptr) {
+ // lock if Q intersects the parents buffer area
+ const MemBlob *P = parent->store_.getRaw();
+ if ( (Q+len) >= P->mem && Q <= (P->mem + P->capacity) )
+ locket = P;
+ }
+ private:
+ MemBlob::Pointer locket;
+ };
+ friend class Locker;
+
MemBlob::Pointer store_; ///< memory block, possibly shared with other SBufs
size_type off_; ///< our content start offset from the beginning of shared store_
size_type len_; ///< number of our content bytes in shared store_