# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: kinkie@squid-cache.org-20090212160911-ni05z3k0tw0hzzek # target_branch: http://www.squid-cache.org/bzr/squid3/trunk # testament_sha1: 7ae0a8ce1ac4ac94fba773dde852e0935bdb9b24 # timestamp: 2009-02-12 17:13:12 +0100 # base_revision_id: chtsanti@users.sourceforge.net-20090211191136-\ # w1pnuweucjfwviiu # # Begin patch === modified file 'src/ACLExtUser.cc' --- src/ACLExtUser.cc 2009-01-29 14:50:26 +0000 +++ src/ACLExtUser.cc 2009-02-10 11:02:53 +0000 @@ -79,7 +79,7 @@ ACLExtUser::match(ACLChecklist *checklist) { if (checklist->request->extacl_user.size()) { - return data->match(checklist->request->extacl_user.unsafeBuf()); + return data->match(checklist->request->extacl_user.termedBuf()); } else { return -1; } === modified file 'src/CommonPool.h' --- src/CommonPool.h 2009-01-29 14:50:26 +0000 +++ src/CommonPool.h 2009-02-11 17:08:24 +0000 @@ -59,7 +59,7 @@ void *operator new(size_t); void operator delete (void *); static CommonPool *Factory (unsigned char _class, CompositePoolNode::Pointer&); - char const* theClassTypeLabel() const {return typeLabel.unsafeBuf();} + char const* theClassTypeLabel() const {return typeLabel.termedBuf();} protected: CommonPool(); === modified file 'src/DelayTagged.cc' --- src/DelayTagged.cc 2009-01-29 14:50:26 +0000 +++ src/DelayTagged.cc 2009-02-11 17:08:24 +0000 @@ -77,7 +77,7 @@ DelayTaggedCmp(DelayTaggedBucket::Pointer const &left, DelayTaggedBucket::Pointer const &right) { /* for rate limiting, case insensitive */ - return left->tag.caseCmp(right->tag.unsafeBuf()); + return left->tag.caseCmp(right->tag); } void @@ -195,7 +195,7 @@ void DelayTaggedBucket::stats (StoreEntry *entry) const { - storeAppendPrintf(entry, " %s:", tag.unsafeBuf()); + storeAppendPrintf(entry, " " SQUIDSTRINGPH , SQUIDSTRINGPRINT(tag)); theBucket.stats (entry); } === modified file 'src/DiskIO/AIO/AIODiskFile.cc' --- src/DiskIO/AIO/AIODiskFile.cc 2009-01-29 14:50:26 +0000 +++ src/DiskIO/AIO/AIODiskFile.cc 2009-02-11 17:08:24 +0000 @@ -87,10 +87,9 @@ { /* Simulate async calls */ #ifdef _SQUID_WIN32_ - fd = aio_open(path.unsafeBuf(), flags); + fd = aio_open(path.termedBuf(), flags); #else - - fd = file_open(path.unsafeBuf() , flags); + fd = file_open(path.termedBuf() , flags); #endif ioRequestor = callback; @@ -130,7 +129,7 @@ fatal("Aiee! out of aiocb slots! - FIXME and wrap file_read\n"); debugs(79, 1, "WARNING: out of aiocb slots!"); /* fall back to blocking method */ - // file_read(fd, request->unsafeBuf, request->len, request->offset, callback, data); + // file_read(fd, request->buf, request->len, request->offset, callback, data); return; } @@ -167,7 +166,7 @@ fatalf("Aiee! aio_read() returned error (%d) FIXME and wrap file_read !\n", errno); debugs(79, 1, "WARNING: aio_read() returned error: " << xstrerror()); /* fall back to blocking method */ - // file_read(fd, request->unsafeBuf, request->len, request->offset, callback, data); + // file_read(fd, request->buf, request->len, request->offset, callback, data); } } @@ -188,7 +187,7 @@ fatal("Aiee! out of aiocb slots FIXME and wrap file_write !\n"); debugs(79, 1, "WARNING: out of aiocb slots!"); /* fall back to blocking method */ - // file_write(fd, offset, unsafeBuf, len, callback, data, freefunc); + // file_write(fd, offset, buf, len, callback, data, freefunc); return; } @@ -225,7 +224,7 @@ fatalf("Aiee! aio_write() returned error (%d) FIXME and wrap file_write !\n", errno); debugs(79, 1, "WARNING: aio_write() returned error: " << xstrerror()); /* fall back to blocking method */ - // file_write(fd, offset, unsafeBuf, len, callback, data, freefunc); + // file_write(fd, offset, buf, len, callback, data, freefunc); } } === modified file 'src/ESI.cc' --- src/ESI.cc 2009-02-04 23:25:42 +0000 +++ src/ESI.cc 2009-02-11 17:08:24 +0000 @@ -2430,7 +2430,7 @@ */ return 0; - if (strstr (sctusable->content.unsafeBuf(), "ESI/1.0")) + if (sctusable->content.pos("ESI/1.0") != NULL) rv = 1; httpHdrScTargetDestroy (sctusable); === modified file 'src/ESIAssign.cc' --- src/ESIAssign.cc 2009-02-04 23:25:42 +0000 +++ src/ESIAssign.cc 2009-02-11 17:08:24 +0000 @@ -89,7 +89,7 @@ variable = NULL; if (unevaluatedVariable.size()) { - varState->feedData(unevaluatedVariable.unsafeBuf(), unevaluatedVariable.size()); + varState->feedData(unevaluatedVariable.rawBuf(), unevaluatedVariable.size()); char const *result = varState->extractChar (); /* Consider activating this, when we want to evaluate variables to a @@ -123,7 +123,7 @@ if (!value) return ESI_PROCESS_COMPLETE; - varState->addVariable (name.unsafeBuf(), name.size(), value); + varState->addVariable (name.rawBuf(), name.size(), value); value = NULL; @@ -194,7 +194,7 @@ ESIVariableExpression::eval (ESIVarState &state, char const *subref, char const *defaultOnEmpty) const { /* XXX: Implement evaluation of the expression */ - ESISegment::ListAppend (state.getOutput(), expression.unsafeBuf(), expression.size()); + ESISegment::ListAppend (state.getOutput(), expression.rawBuf(), expression.size()); } #endif /* USE_SQUID_ESI == 1 */ === modified file 'src/ESICustomParser.cc' --- src/ESICustomParser.cc 2009-02-04 23:25:42 +0000 +++ src/ESICustomParser.cc 2009-02-10 11:02:53 +0000 @@ -109,7 +109,8 @@ } size_t openESITags (0); - char const *currentPos = content.unsafeBuf(); + //erring on the safe side. Probably rawBuf would be ok too + char const *currentPos = content.termedBuf(); size_t remainingCount = content.size(); char const *tag = NULL; @@ -302,7 +303,7 @@ ESICustomParser::errorString() const { if (error.size()) - return error.unsafeBuf(); + return error.termedBuf(); else return "Parsing error strings not implemented"; } === modified file 'src/ESISegment.cc' --- src/ESISegment.cc 2009-02-04 23:25:42 +0000 +++ src/ESISegment.cc 2009-02-06 00:59:06 +0000 @@ -236,5 +236,5 @@ { String temp; temp.limitInit(buf, len); - debugs(86, 9, "ESISegment::dumpOne: \"" << temp.unsafeBuf() << "\""); + debugs(86, 9, "ESISegment::dumpOne: \"" << temp << "\""); } === modified file 'src/HttpHdrCc.cc' --- src/HttpHdrCc.cc 2009-01-31 17:04:05 +0000 +++ src/HttpHdrCc.cc 2009-02-12 16:06:20 +0000 @@ -235,9 +235,8 @@ if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) { /* print option name */ - packerPrintf(p, (pcount ? ", %.*s" : "%.*s"), - CcFieldsInfo[flag].name.size(), - CcFieldsInfo[flag].name.rawBuf()); + packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH), + SQUIDSTRINGPRINT(CcFieldsInfo[flag].name)); /* handle options with values */ @@ -254,9 +253,9 @@ } } - if (cc->other.size()) - packerPrintf(p, (pcount ? ", %.*s" : "%.*s"), - cc->other.size(), cc->other.rawBuf()); + if (cc->other.size() != 0) + packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH), + SQUIDSTRINGPRINT(cc->other)); } /* negative max_age will clean old max_Age setting */ === modified file 'src/HttpHdrSc.cc' --- src/HttpHdrSc.cc 2009-01-31 17:23:17 +0000 +++ src/HttpHdrSc.cc 2009-02-12 16:06:20 +0000 @@ -257,9 +257,8 @@ if (EBIT_TEST(sc->mask, flag) && flag != SC_OTHER) { /* print option name */ - packerPrintf(p, (pcount ? ", %.*s" : "%.*s"), - ScFieldsInfo[flag].name.size(), - ScFieldsInfo[flag].name.rawBuf()); + packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH), + SQUIDSTRINGPRINT(ScFieldsInfo[flag].name)); /* handle options with values */ @@ -267,14 +266,14 @@ packerPrintf(p, "=%d", (int) sc->max_age); if (flag == SC_CONTENT) - packerPrintf(p, "=\"%.*s\"", sc->content.size(), sc->content.rawBuf()); + packerPrintf(p, "=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(sc->content)); pcount++; } } if (sc->target.size()) - packerPrintf (p, ";%.*s", sc->target.size(), sc->target.rawBuf()); + packerPrintf (p, ";" SQUIDSTRINGPH, SQUIDSTRINGPRINT(sc->target)); } void === modified file 'src/HttpHeader.cc' --- src/HttpHeader.cc 2009-01-31 18:23:44 +0000 +++ src/HttpHeader.cc 2009-02-09 15:47:31 +0000 @@ -1683,7 +1683,7 @@ } http_hdr_type -httpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * info, int end) +httpHeaderIdByName(const char *name, size_t name_len, const HttpHeaderFieldInfo * info, int end) { int i; === modified file 'src/HttpHeader.h' --- src/HttpHeader.h 2009-01-21 03:47:47 +0000 +++ src/HttpHeader.h 2009-02-11 15:28:22 +0000 @@ -33,12 +33,21 @@ #ifndef SQUID_HTTPHEADER_H #define SQUID_HTTPHEADER_H - /* because we pass a spec by value */ #include "HttpHeaderRange.h" /* HttpHeader holds a HttpHeaderMask */ #include "HttpHeaderMask.h" + +/* class forward declarations */ +class HttpVersion; +class HttpHdrContRange; +class HttpHdrCc; +class HttpHdrSc; +class HttpHdrRange; +class String; + + /* constant attributes of http header fields */ /** recognized or "known" header fields; @?@ add more! */ @@ -149,13 +158,6 @@ field_type type; }; -class HttpVersion; - -class HttpHdrContRange; - -class HttpHdrCc; - -class HttpHdrSc; /** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */ typedef ssize_t HttpHeaderPos; === modified file 'src/HttpReply.cc' --- src/HttpReply.cc 2009-02-04 13:48:24 +0000 +++ src/HttpReply.cc 2009-02-09 15:47:31 +0000 @@ -439,7 +439,7 @@ bool HttpReply::sanityCheckStartLine(MemBuf *buf, http_status *error) { - if (buf->contentSize() >= protoPrefix.size() && protoPrefix.cmp(buf->content(), protoPrefix.size()) != 0) { + if (buf->contentSize() >= protoPrefix.psize() && protoPrefix.cmp(buf->content(), protoPrefix.size()) != 0) { //hack debugs(58, 3, "HttpReply::sanityCheckStartLine: missing protocol prefix (" << protoPrefix << ") in '" << buf->content() << "'"); *error = HTTP_INVALID_HEADER; return false; === modified file 'src/HttpRequest.cc' --- src/HttpRequest.cc 2009-02-09 05:33:18 +0000 +++ src/HttpRequest.cc 2009-02-12 16:06:20 +0000 @@ -298,8 +298,8 @@ { assert(p); /* pack request-line */ - packerPrintf(p, "%s %.*s HTTP/1.0\r\n", - RequestMethodStr(method), urlpath.size(), urlpath.rawBuf()); + packerPrintf(p, "%s " SQUIDSTRINGPH " HTTP/1.0\r\n", + RequestMethodStr(method), SQUIDSTRINGPRINT(urlpath)); /* headers */ header.packInto(p); /* trailer */ === modified file 'src/ICAP/ICAPModXact.cc' --- src/ICAP/ICAPModXact.cc 2009-01-31 16:05:18 +0000 +++ src/ICAP/ICAPModXact.cc 2009-02-12 16:06:20 +0000 @@ -1029,8 +1029,8 @@ * XXX These should use HttpHdr interfaces instead of Printfs */ const Adaptation::ServiceConfig &s = service().cfg(); - buf.Printf("%s %.*s ICAP/1.0\r\n", s.methodStr(), s.uri.size(), s.uri.rawBuf()); - buf.Printf("Host: %.*s:%d\r\n", s.host.size(), s.host.rawBuf(), s.port); + buf.Printf("%s " SQUIDSTRINGPH " ICAP/1.0\r\n", s.methodStr(), SQUIDSTRINGPRINT(s.uri)); + buf.Printf("Host: " SQUIDSTRINGPH ":%d\r\n", SQUIDSTRINGPRINT(s.host), s.port); buf.Printf("Date: %s\r\n", mkrfc1123(squid_curtime)); if (!TheICAPConfig.reuse_connections) @@ -1040,14 +1040,12 @@ // as ICAP headers. if (virgin.header->header.has(HDR_PROXY_AUTHENTICATE)) { String vh=virgin.header->header.getByName("Proxy-Authenticate"); - buf.Printf("Proxy-Authenticate: %.*s\r\n", - vh.size(), vh.rawBuf()); + buf.Printf("Proxy-Authenticate: " SQUIDSTRINGPH "\r\n",SQUIDSTRINGPRINT(vh)); } if (virgin.header->header.has(HDR_PROXY_AUTHORIZATION)) { String vh=virgin.header->header.getByName("Proxy-Authorization"); - buf.Printf("Proxy-Authorization: %.*s\r\n", - vh.size(), vh.rawBuf()); + buf.Printf("Proxy-Authorization: " SQUIDSTRINGPH "\r\n", SQUIDSTRINGPRINT(vh)); } buf.Printf("Encapsulated: "); @@ -1111,7 +1109,7 @@ if (TheICAPConfig.send_client_username && request) makeUsernameHeader(request, buf); - // fprintf(stderr, "%s\n", unsafeBuf.content()); + // fprintf(stderr, "%s\n", buf.content()); buf.append(ICAP::crlf, 2); // terminate ICAP header @@ -1272,7 +1270,7 @@ Must(!preview.ad()); // do not add last-chunk because our Encapsulated header says null-body - // addLastRequestChunk(unsafeBuf); + // addLastRequestChunk(buf); preview.wrote(0, true); Must(preview.done()); === modified file 'src/ICAP/ICAPOptXact.cc' --- src/ICAP/ICAPOptXact.cc 2009-01-30 14:55:22 +0000 +++ src/ICAP/ICAPOptXact.cc 2009-02-12 16:06:20 +0000 @@ -44,9 +44,9 @@ { const Adaptation::Service &s = service(); const String uri = s.cfg().uri; - buf.Printf("OPTIONS %.*s ICAP/1.0\r\n", uri.size(), uri.rawBuf()); + buf.Printf("OPTIONS " SQUIDSTRINGPH " ICAP/1.0\r\n", SQUIDSTRINGPRINT(uri)); const String host = s.cfg().host; - buf.Printf("Host: %.*s:%d\r\n", host.size(), host.rawBuf(), s.cfg().port); + buf.Printf("Host: " SQUIDSTRINGPH ":%d\r\n", SQUIDSTRINGPRINT(host), s.cfg().port); buf.append(ICAP::crlf, 2); } === modified file 'src/ICAP/ICAPServiceRep.cc' --- src/ICAP/ICAPServiceRep.cc 2009-01-30 14:55:22 +0000 +++ src/ICAP/ICAPServiceRep.cc 2009-02-10 11:02:53 +0000 @@ -279,7 +279,7 @@ if (!method_found) { debugs(93,1, "WARNING: Squid is configured to use ICAP method " << cfg().methodStr() << - " for service " << cfg().uri.unsafeBuf() << + " for service " << cfg().uri << " but OPTIONS response declares the methods are " << method_list); } } @@ -293,7 +293,7 @@ // TODO: If skew is negative, the option will be considered down // because of stale options. We should probably change this. debugs(93, 1, "ICAP service's clock is skewed by " << skew << - " seconds: " << cfg().uri.unsafeBuf()); + " seconds: " << cfg().uri); } } === modified file 'src/ICAP/ICAPXaction.cc' --- src/ICAP/ICAPXaction.cc 2009-01-29 14:50:26 +0000 +++ src/ICAP/ICAPXaction.cc 2009-02-11 17:08:24 +0000 @@ -76,7 +76,7 @@ disableRetries(); // this will also safely drain pconn pool // TODO: check whether NULL domain is appropriate here - connection = icapPconnPool->pop(s.cfg().host.unsafeBuf(), s.cfg().port, NULL, client_addr, isRetriable); + connection = icapPconnPool->pop(s.cfg().host.termedBuf(), s.cfg().port, NULL, client_addr, isRetriable); if (connection >= 0) { debugs(93,3, HERE << "reused pconn FD " << connection); @@ -96,12 +96,12 @@ IpAddress outgoing; connection = comm_open(SOCK_STREAM, 0, outgoing, - COMM_NONBLOCKING, s.cfg().uri.unsafeBuf()); + COMM_NONBLOCKING, s.cfg().uri.termedBuf()); if (connection < 0) dieOnConnectionFailure(); // throws - debugs(93,3, typeName << " opens connection to " << s.cfg().host.unsafeBuf() << ":" << s.cfg().port); + debugs(93,3, typeName << " opens connection to " << s.cfg().host << ":" << s.cfg().port); // TODO: service bypass status may differ from that of a transaction typedef CommCbMemFunT TimeoutDialer; @@ -119,7 +119,7 @@ typedef CommCbMemFunT ConnectDialer; connector = asyncCall(93,3, "ICAPXaction::noteCommConnected", ConnectDialer(this, &ICAPXaction::noteCommConnected)); - commConnectStart(connection, s.cfg().host.unsafeBuf(), s.cfg().port, connector); + commConnectStart(connection, s.cfg().host.termedBuf(), s.cfg().port, connector); } /* @@ -157,7 +157,7 @@ debugs(93,3, HERE << "pushing pconn" << status()); AsyncCall::Pointer call = NULL; commSetTimeout(connection, -1, call); - icapPconnPool->push(connection, theService->cfg().host.unsafeBuf(), + icapPconnPool->push(connection, theService->cfg().host.termedBuf(), theService->cfg().port, NULL, client_addr); disableRetries(); } else { @@ -232,7 +232,7 @@ { debugs(93, 2, HERE << typeName << " failed: timeout with " << theService->cfg().methodStr() << " " << - theService->cfg().uri.unsafeBuf() << status()); + theService->cfg().uri << status()); reuseConnection = false; service().noteFailure(); @@ -295,7 +295,7 @@ /* * See comments in ICAPXaction.h about why we use commBuf - * here instead of reading directly into readBuf.unsafeBuf. + * here instead of reading directly into readBuf.buf. */ typedef CommCbMemFunT Dialer; reader = asyncCall(93,3, "ICAPXaction::noteCommRead", @@ -320,7 +320,7 @@ /* * See comments in ICAPXaction.h about why we use commBuf - * here instead of reading directly into readBuf.unsafeBuf. + * here instead of reading directly into readBuf.buf. */ if (io.size > 0) { === modified file 'src/Makefile.am' --- src/Makefile.am 2009-02-02 12:33:27 +0000 +++ src/Makefile.am 2009-02-11 15:28:22 +0000 @@ -1512,6 +1512,7 @@ $(SWAP_TEST_GEN_SOURCES) tests_testDiskIO_LDADD = \ ip/libip.la \ + libsquid.la \ @DISK_LIBS@ \ $(SWAP_TEST_LDADD) \ SquidConfig.o === modified file 'src/SquidString.h' --- src/SquidString.h 2009-02-04 22:39:55 +0000 +++ src/SquidString.h 2009-02-12 16:06:20 +0000 @@ -40,6 +40,12 @@ /** todo checks to wrap this include properly */ #include +/* squid string placeholder (for printf) */ +#ifndef SQUIDSTRINGPH +#define SQUIDSTRINGPH "%.*s" +#define SQUIDSTRINGPRINT(s) s.psize(),s.rawBuf() +#endif /* SQUIDSTRINGPH */ + #define DEBUGSTRINGS 0 #if DEBUGSTRINGS @@ -86,6 +92,9 @@ String (String const &); ~String(); + typedef size_t size_type; //storage size intentionally unspecified + const static size_type npos = std::string::npos; + String &operator =(char const *); String &operator =(String const &); bool operator ==(String const &) const; @@ -97,8 +106,10 @@ */ _SQUID_INLINE_ char operator [](unsigned int pos) const; - _SQUID_INLINE_ int size() const; - _SQUID_INLINE_ char const * unsafeBuf() const; + _SQUID_INLINE_ size_type size() const; + /// variant of size() suited to be used for printf-alikes. + /// throws when size() > MAXINT + int psize() const; /** * \retval true the String has some contents @@ -126,33 +137,28 @@ void append(char const); void append (String const &); void absorb(String &old); - _SQUID_INLINE_ const char * pos(char const *) const; - _SQUID_INLINE_ const char * pos(char const ch) const; + const char * pos(char const *aString) const; + const char * pos(char const ch) const; ///offset from string start of the first occurrence of ch - /// returns std::string::npos if ch is not found - _SQUID_INLINE_ size_t find(char const ch) const; - _SQUID_INLINE_ const char * rpos(char const ch) const; + /// returns String::npos if ch is not found + size_type find(char const ch) const; + size_type find(char const *aString) const; + const char * rpos(char const ch) const; + size_type rfind(char const ch) const; _SQUID_INLINE_ int cmp (char const *) const; - _SQUID_INLINE_ int cmp (char const *, size_t count) const; + _SQUID_INLINE_ int cmp (char const *, size_type count) const; _SQUID_INLINE_ int cmp (String const &) const; _SQUID_INLINE_ int caseCmp (char const *) const; - _SQUID_INLINE_ int caseCmp (char const *, size_t count) const; + _SQUID_INLINE_ int caseCmp (char const *, size_type count) const; _SQUID_INLINE_ int caseCmp (String const &) const; - /** \deprecated Use assignment to [] position instead. - * ie str[0] = 'h'; - */ - _SQUID_INLINE_ void set(char const *loc, char const ch); - - /** \deprecated Use assignment to [] position instead. - * ie str[newLength] = '\0'; - */ - _SQUID_INLINE_ void cut(size_t newLength); - - /** \deprecated Use assignment to [] position instead. - * ie str[newLength] = '\0'; - */ - _SQUID_INLINE_ void cutPointer(char const *loc); + String substr(size_type from, size_type to) const; + + /** \deprecated Use assignment to [] position instead. + * ie str[newLength] = '\0'; + */ + _SQUID_INLINE_ void cut(size_type newLength); + #if DEBUGSTRINGS @@ -164,15 +170,19 @@ private: void allocAndFill(const char *str, int len); - void allocBuffer(size_t sz); - void setBuffer(char *buf, size_t sz); + void allocBuffer(size_type sz); + void setBuffer(char *buf, size_type sz); /* never reference these directly! */ - unsigned short int size_; /* buffer size; 64K limit */ + size_type size_; /* buffer size; 64K limit */ - unsigned short int len_; /* current length */ + size_type len_; /* current length */ char *buf_; + + _SQUID_INLINE_ void set(char const *loc, char const ch); + _SQUID_INLINE_ void cutPointer(char const *loc); + }; _SQUID_INLINE_ std::ostream & operator<<(std::ostream& os, String const &aString); === modified file 'src/String.cc' --- src/String.cc 2009-02-03 17:36:15 +0000 +++ src/String.cc 2009-02-12 16:06:20 +0000 @@ -35,11 +35,20 @@ #include "squid.h" #include "Store.h" +#include "TextException.h" + +int +String::psize() const +{ + Must(size() < INT_MAX); + return size(); +} + // low-level buffer allocation, // does not free old buffer and does not adjust or look at len_ void -String::allocBuffer(size_t sz) +String::allocBuffer(String::size_type sz) { PROF_start(StringInitBuf); assert (undefined()); @@ -51,7 +60,7 @@ // low-level buffer assignment // does not free old buffer and does not adjust or look at len_ void -String::setBuffer(char *aBuf, size_t aSize) +String::setBuffer(char *aBuf, String::size_type aSize) { assert(undefined()); assert(aSize < 65536); @@ -233,6 +242,19 @@ old.len_ = 0; } +String +String::substr(String::size_type from, String::size_type to) const +{ + Must(from >= 0 && from < size()); + Must(to > 0 && to <= size()); + Must(to > from); + + String rv; + rv.limitInit(rawBuf()+from,to-from); + return rv; +} + + #if DEBUGSTRINGS void String::stat(StoreEntry *entry) const @@ -279,7 +301,7 @@ StringRegistry StringRegistry::Instance_; -extern size_t memStringCount(); +extern String::size_type memStringCount(); void StringRegistry::Stat(StoreEntry *entry) @@ -412,6 +434,56 @@ return p ? p : "(NULL)"; } +const char * +String::pos(char const *aString) const +{ + return strstr(termedBuf(), aString); +} + +const char * +String::pos(char const ch) const +{ + return strchr(termedBuf(), ch); +} + +const char * +String::rpos(char const ch) const +{ + return strrchr(termedBuf(), (ch)); +} + +String::size_type +String::find(char const ch) const +{ + const char *c; + c=pos(ch); + if (c==NULL) + return npos; + return c-rawBuf(); +} + +String::size_type +String::find(char const *aString) const +{ + const char *c; + c=pos(aString); + if (c==NULL) + return npos; + return c-rawBuf(); +} + +String::size_type +String::rfind(char const ch) const +{ + const char *c; + c=rpos(ch); + if (c==NULL) + return npos; + return c-rawBuf(); +} + + + #ifndef _USE_INLINE_ #include "String.cci" #endif === modified file 'src/String.cci' --- src/String.cci 2009-02-04 22:39:55 +0000 +++ src/String.cci 2009-02-12 16:06:20 +0000 @@ -34,6 +34,16 @@ #include "assert.h" #include +#include "squid.h" + +#ifdef HAVE_STDINT_H +#include //for INT_MAX +#else /* HAVE_STDINT_H */ +#ifndef INT_MAX +#define INT_MAX 1<<31 //hack but a safe bet +#endif /* INT_MAX */ +#endif /* HAVE_STDINT_H */ + String::String() : size_(0), len_(0), buf_ (NULL) { @@ -42,18 +52,12 @@ #endif } -int +String::size_type String::size() const { return len_; } -char const * -String::unsafeBuf() const -{ - return buf_; -} - bool String::defined() const { return buf_!=NULL; @@ -84,33 +88,6 @@ return buf_[pos]; } -const char * -String::pos(char const *aString) const -{ - return strstr(termedBuf(), aString); -} - -const char * -String::pos(char const ch) const -{ - return strchr(termedBuf(), ch); -} - -size_t -String::find(char const ch) const -{ - const char *c; - c=pos(ch); - if (c==NULL) - return std::string::npos; - return c-rawBuf(); -} - -const char * -String::rpos(char const ch) const -{ - return strrchr(termedBuf(), (ch)); -} int String::cmp (char const *aString) const @@ -130,7 +107,7 @@ } int -String::cmp (char const *aString, size_t count) const +String::cmp (char const *aString, String::size_type count) const { /* always the same at length 0 */ @@ -173,7 +150,7 @@ } int -String::caseCmp(char const *aString, size_t count) const +String::caseCmp(char const *aString, String::size_type count) const { return strncasecmp(termedBuf(), aString, count); } @@ -194,7 +171,7 @@ } void -String::cut(size_t newLength) +String::cut(String::size_type newLength) { if (newLength < 0 || newLength > len_) return; === modified file 'src/access_log.cc' --- src/access_log.cc 2009-01-29 14:50:26 +0000 +++ src/access_log.cc 2009-02-06 00:59:06 +0000 @@ -625,7 +625,7 @@ if (al->request) sb = al->request->header.getByName(fmt->data.header.header); - out = sb.unsafeBuf(); + out = sb.termedBuf(); quote = 1; @@ -635,7 +635,7 @@ if (al->reply) sb = al->reply->header.getByName(fmt->data.header.header); - out = sb.unsafeBuf(); + out = sb.termedBuf(); quote = 1; @@ -645,7 +645,7 @@ if (al->request) sb = al->request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator); - out = sb.unsafeBuf(); + out = sb.termedBuf(); quote = 1; @@ -655,7 +655,7 @@ if (al->reply) sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator); - out = sb.unsafeBuf(); + out = sb.termedBuf(); quote = 1; @@ -764,7 +764,7 @@ case LFT_REQUEST_URLPATH: if (al->request) { - out = al->request->urlpath.unsafeBuf(); + out = al->request->urlpath.termedBuf(); quote = 1; } break; @@ -810,7 +810,7 @@ case LFT_TAG: if (al->request) - out = al->request->tag.unsafeBuf(); + out = al->request->tag.termedBuf(); quote = 1; @@ -823,7 +823,7 @@ case LFT_EXT_LOG: if (al->request) - out = al->request->extacl_log.unsafeBuf(); + out = al->request->extacl_log.termedBuf(); quote = 1; === modified file 'src/adaptation/Config.cc' --- src/adaptation/Config.cc 2009-02-11 19:11:36 +0000 +++ src/adaptation/Config.cc 2009-02-12 16:09:11 +0000 @@ -68,8 +68,11 @@ typedef Services::iterator SCI; for (SCI i = AllServices().begin(); i != AllServices().end(); ++i) { const ServiceConfig &cfg = (*i)->cfg(); - storeAppendPrintf(entry, "%s %.*s_%s %s %d %.*s\n", name, cfg.key.size(), cfg.key.rawBuf(), - cfg.methodStr(), cfg.vectPointStr(), cfg.bypass, cfg.uri.size(), cfg.uri.rawBuf()); + storeAppendPrintf(entry, "%s " SQUIDSTRINGPH "_%s %s %d " SQUIDSTRINGPH "\n", + name, + SQUIDSTRINGPRINT(cfg.key), + cfg.methodStr(), cfg.vectPointStr(), cfg.bypass, + SQUIDSTRINGPRINT(cfg.uri)); } } @@ -141,7 +144,7 @@ { typedef Groups::iterator GI; for (GI i = AllGroups().begin(); i != AllGroups().end(); ++i) - storeAppendPrintf(entry, "%s %s\n", name, (*i)->id.unsafeBuf()); + storeAppendPrintf(entry, "%s " SQUIDSTRINGPH "\n", name, SQUIDSTRINGPRINT((*i)->id)); } void @@ -186,7 +189,7 @@ typedef AccessRules::iterator CI; for (CI i = AllRules().begin(); i != AllRules().end(); ++i) { - snprintf(nom, 64, "%s %s", name, (*i)->groupId.unsafeBuf()); + snprintf(nom, 64, "%s " SQUIDSTRINGPH, name, SQUIDSTRINGPRINT((*i)->groupId)); dump_acl_access(entry, nom, (*i)->acl); } } === modified file 'src/adaptation/ServiceConfig.cc' --- src/adaptation/ServiceConfig.cc 2009-02-03 23:13:10 +0000 +++ src/adaptation/ServiceConfig.cc 2009-02-12 16:06:20 +0000 @@ -76,11 +76,13 @@ // extract scheme and use it as the service_configConfig protocol const char *schemeSuffix = "://"; - if (const char *schemeEnd = uri.pos(schemeSuffix)) - protocol.limitInit(uri.rawBuf(), schemeEnd - uri.rawBuf()); //substring + if (const String::size_type schemeEnd=uri.find(schemeSuffix)) + protocol=uri.substr(0,schemeEnd-1); + debugs(3, 5, HERE << cfg_filename << ':' << config_lineno << ": " << "service protocol is " << protocol); - if (!protocol.size()) + + if (protocol.size() == 0) return false; // skip scheme === modified file 'src/client_side.cc' --- src/client_side.cc 2009-02-06 07:54:05 +0000 +++ src/client_side.cc 2009-02-12 16:06:20 +0000 @@ -489,7 +489,7 @@ al.http.content_type = al.reply->content_type.termedBuf(); } else if (loggingEntry() && loggingEntry()->mem_obj) { al.http.code = loggingEntry()->mem_obj->getReply()->sline.status; - al.http.content_type = loggingEntry()->mem_obj->getReply()->content_type.unsafeBuf(); + al.http.content_type = loggingEntry()->mem_obj->getReply()->content_type.termedBuf(); } debugs(33, 9, "clientLogRequest: http.code='" << al.http.code << "'"); @@ -852,7 +852,7 @@ static void clientPackTermBound(String boundary, MemBuf * mb) { - mb->Printf("\r\n--%.*s--\r\n", boundary.size(), boundary.rawBuf()); + mb->Printf("\r\n--" SQUIDSTRINGPH "--\r\n", SQUIDSTRINGPRINT(boundary)); debugs(33, 6, "clientPackTermBound: buf offset: " << mb->size); } @@ -868,7 +868,7 @@ /* put boundary */ debugs(33, 5, "clientPackRangeHdr: appending boundary: " << boundary); /* rfc2046 requires to _prepend_ boundary with ! */ - mb->Printf("\r\n--%.*s\r\n", boundary.size(), boundary.rawBuf()); + mb->Printf("\r\n--" SQUIDSTRINGPH "\r\n", SQUIDSTRINGPRINT(boundary)); /* stuff the header with required entries and pack it */ @@ -890,7 +890,7 @@ } /** - * extracts a "range" from *unsafeBuf and appends them to mb, updating + * extracts a "range" from *buf and appends them to mb, updating * all offsets and such. */ void @@ -1168,8 +1168,8 @@ /* delete old Content-Type, add ours */ hdr->delById(HDR_CONTENT_TYPE); httpHeaderPutStrf(hdr, HDR_CONTENT_TYPE, - "multipart/byteranges; boundary=\"%s\"", - http->range_iter.boundary.unsafeBuf()); + "multipart/byteranges; boundary=\"" SQUIDSTRINGPH "\"", + SQUIDSTRINGPRINT(http->range_iter.boundary)); /* Content-Length is not required in multipart responses * but it is always nice to have one */ actual_clen = http->mRangeCLen(); @@ -1923,7 +1923,7 @@ req_sz = HttpParserReqSz(hp); } - /* We know the whole request is in hp->unsafeBuf now */ + /* We know the whole request is in hp->buf now */ assert(req_sz <= (size_t) hp->bufsiz); @@ -2622,7 +2622,7 @@ } /** - * called when new request body data has been buffered in in.unsafeBuf + * called when new request body data has been buffered in in.buf * may close the connection if we were closing and piped everything out */ void === modified file 'src/client_side_reply.cc' --- src/client_side_reply.cc 2009-02-04 13:48:24 +0000 +++ src/client_side_reply.cc 2009-02-11 17:08:24 +0000 @@ -1671,7 +1671,7 @@ } /* - * accepts chunk of a http message in unsafeBuf, parses prefix, filters headers and + * accepts chunk of a http message in buf, parses prefix, filters headers and * such, writes processed message to the message recipient */ void === modified file 'src/client_side_request.cc' --- src/client_side_request.cc 2009-02-04 22:39:55 +0000 +++ src/client_side_request.cc 2009-02-11 17:08:24 +0000 @@ -426,7 +426,7 @@ const char *asciiaddr; int l; struct in_addr addr; - p = request->x_forwarded_for_iterator.unsafeBuf(); + p = request->x_forwarded_for_iterator.termedBuf(); l = request->x_forwarded_for_iterator.size(); /* @@ -897,7 +897,7 @@ } #if FORW_VIA_DB - fvdbCountVia(s.unsafeBuf()); + fvdbCountVia(s.termedBuf()); #endif @@ -923,7 +923,7 @@ if (req_hdr->has(HDR_X_FORWARDED_FOR)) { String s = req_hdr->getList(HDR_X_FORWARDED_FOR); - fvdbCountForw(s.unsafeBuf()); + fvdbCountForw(s.termedBuf()); s.clean(); } === modified file 'src/eCAP/MessageRep.cc' --- src/eCAP/MessageRep.cc 2009-01-29 16:14:56 +0000 +++ src/eCAP/MessageRep.cc 2009-02-11 17:08:24 +0000 @@ -192,7 +192,7 @@ Ecap::RequestLineRep::Area Ecap::RequestLineRep::uri() const { - return Area::FromTempBuffer(theMessage.urlpath.unsafeBuf(), + return Area::FromTempBuffer(theMessage.urlpath.rawBuf(), theMessage.urlpath.size()); } === modified file 'src/errorpage.cc' --- src/errorpage.cc 2009-01-29 14:50:26 +0000 +++ src/errorpage.cc 2009-02-11 17:08:24 +0000 @@ -556,9 +556,16 @@ if (NULL != request) { Packer p; - str.Printf("%s %s HTTP/%d.%d\n", + String urlpath_or_slash; + + if (request->urlpath.size() != 0) + urlpath_or_slash = request->urlpath; + else + urlpath_or_slash = "/"; + + str.Printf("%s " SQUIDSTRINGPH " HTTP/%d.%d\n", RequestMethodStr(request->method), - request->urlpath.size() ? request->urlpath.unsafeBuf() : "/", + SQUIDSTRINGPRINT(urlpath_or_slash), request->http_ver.major, request->http_ver.minor); packerToMemInit(&p, &str); request->header.packInto(&p); @@ -734,9 +741,16 @@ if (NULL != request) { Packer p; - mb.Printf("%s %s HTTP/%d.%d\n", + String urlpath_or_slash; + + if (request->urlpath.size() != 0) + urlpath_or_slash = request->urlpath; + else + urlpath_or_slash = "/"; + + mb.Printf("%s " SQUIDSTRINGPH " HTTP/%d.%d\n", RequestMethodStr(request->method), - request->urlpath.size() ? request->urlpath.unsafeBuf() : "/", + SQUIDSTRINGPRINT(urlpath_or_slash), request->http_ver.major, request->http_ver.minor); packerToMemInit(&p, &mb); request->header.packInto(&p); @@ -928,8 +942,8 @@ */ if (!Config.errorDirectory && request && request->header.getList(HDR_ACCEPT_LANGUAGE, &hdr) ) { - const char *unsafeBuf = hdr.unsafeBuf(); // raw header string for parsing - int pos = 0; // current parsing position in header string + const char *raw_hdr = hdr.termedBuf(); // raw header string for parsing + size_t pos = 0; // current parsing position in header string char *reset = NULL; // where to reset the p pointer for each new tag file char *dt = NULL; @@ -950,12 +964,12 @@ * - IFF a tag contains only two characters we can wildcard ANY translations matching: '-'? .* * with preference given to an exact match. */ - while (pos < hdr.size() && unsafeBuf[pos] != ';' && unsafeBuf[pos] != ',' && !xisspace(unsafeBuf[pos]) && dt < (dir+256) ) { - *dt++ = xtolower(unsafeBuf[pos++]); + while (pos < hdr.size() && raw_hdr[pos] != ';' && raw_hdr[pos] != ',' && !xisspace(raw_hdr[pos]) && dt < (dir+256) ) { + *dt++ = xtolower(raw_hdr[pos++]); } *dt++ = '\0'; // nul-terminated the filename content string before system use. - debugs(4, 9, HERE << "STATE: dt='" << dt << "', reset='" << reset << "', reset[1]='" << reset[1] << "', pos=" << pos << ", buf='" << &unsafeBuf[pos] << "'"); + debugs(4, 9, HERE << "STATE: dt='" << dt << "', reset='" << reset << "', reset[1]='" << reset[1] << "', pos=" << pos << ", buf='" << &raw_hdr[pos] << "'"); /* if we found anything we might use, try it. */ if (*reset != '\0') { @@ -983,8 +997,8 @@ dt = reset; // reset for next tag testing. we replace the failed name instead of cloning. // IFF we terminated the tag on ';' we need to skip the 'q=' bit to the next ',' or end. - while (pos < hdr.size() && unsafeBuf[pos] != ',') pos++; - if (unsafeBuf[pos] == ',') pos++; + while (pos < hdr.size() && raw_hdr[pos] != ',') pos++; + if (raw_hdr[pos] == ',') pos++; } } #endif /* USE_ERR_LOCALES */ === modified file 'src/external_acl.cc' --- src/external_acl.cc 2009-02-05 10:59:06 +0000 +++ src/external_acl.cc 2009-02-10 11:02:53 +0000 @@ -753,7 +753,7 @@ external_acl_cache_touch(acl->def, entry); result = entry->result; - external_acl_message = entry->message.unsafeBuf(); + external_acl_message = entry->message.termedBuf(); debugs(82, 2, "aclMatchExternal: " << acl->def->name << " = " << result); === modified file 'src/ftp.cc' --- src/ftp.cc 2009-02-03 23:13:10 +0000 +++ src/ftp.cc 2009-02-12 16:06:20 +0000 @@ -1445,16 +1445,20 @@ return 0; /* different username */ } +static String str_type_eq; void FtpStateData::checkUrlpath() { int l; - const char *t; - - if ((t = request->urlpath.rpos(';')) != NULL) { - if (strncasecmp(t + 1, "type=", 5) == 0) { - typecode = (char) xtoupper(*(t + 6)); - request->urlpath.cutPointer(t); + size_t t; + + if (str_type_eq.undefined()) //hack. String doesn't support global-static + str_type_eq="type="; + + if ((t = request->urlpath.rfind(';')) != String::npos) { + if (request->urlpath.substr(t+1,t+1+str_type_eq.size())==str_type_eq) { + typecode = (char)xtoupper(request->urlpath[t+str_type_eq.size()+1]); + request->urlpath.cut(t); } } @@ -3742,7 +3746,7 @@ request->urlpath.absorb(newbuf); safe_free(request->canonical); } else if ( !strncmp(request->urlpath.termedBuf(), "%2f", 3) ) { - newbuf.append(request->urlpath.rawBuf() +1, request->urlpath.size()-1); + newbuf.append(request->urlpath.substr(1,request->urlpath.size())); request->urlpath.absorb(newbuf); safe_free(request->canonical); } === modified file 'src/gopher.cc' --- src/gopher.cc 2009-01-31 16:40:06 +0000 +++ src/gopher.cc 2009-02-11 17:08:24 +0000 @@ -853,7 +853,7 @@ do_next_read = 0; } else if (len == 0) { /* Connection closed; retrieval done. */ - /* flush the rest of data in temp unsafeBuf if there is one. */ + /* flush the rest of data in temp buf if there is one. */ if (gopherState->conversion != gopher_ds::NORMAL) gopherEndHTML(gopherState); === modified file 'src/http.cc' --- src/http.cc 2009-02-09 10:52:15 +0000 +++ src/http.cc 2009-02-12 16:06:20 +0000 @@ -1542,11 +1542,9 @@ } else if (strcmp(orig_request->peer_login, "PASS") == 0) { if (orig_request->extacl_user.size() && orig_request->extacl_passwd.size()) { char loginbuf[256]; - snprintf(loginbuf, sizeof(loginbuf), "%.*s:%.*s", - orig_request->extacl_user.size(), - orig_request->extacl_user.rawBuf(), - orig_request->extacl_passwd.size(), - orig_request->extacl_passwd.rawBuf()); + snprintf(loginbuf, sizeof(loginbuf), SQUIDSTRINGPH ":" SQUIDSTRINGPH, + SQUIDSTRINGPRINT(orig_request->extacl_user), + SQUIDSTRINGPRINT(orig_request->extacl_passwd)); httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s", base64_encode(loginbuf)); } @@ -1573,11 +1571,9 @@ hdr_out->putStr(HDR_AUTHORIZATION, auth); } else if (orig_request->extacl_user.size() && orig_request->extacl_passwd.size()) { char loginbuf[256]; - snprintf(loginbuf, sizeof(loginbuf), "%.*s:%.*s", - orig_request->extacl_user.size(), - orig_request->extacl_user.rawBuf(), - orig_request->extacl_passwd.size(), - orig_request->extacl_passwd.rawBuf()); + snprintf(loginbuf, sizeof(loginbuf), SQUIDSTRINGPH ":" SQUIDSTRINGPH, + SQUIDSTRINGPRINT(orig_request->extacl_user), + SQUIDSTRINGPRINT(orig_request->extacl_passwd)); httpHeaderPutStrf(hdr_out, HDR_AUTHORIZATION, "Basic %s", base64_encode(loginbuf)); } @@ -1808,7 +1804,7 @@ * pass on all other header fields * which are NOT listed by the special Connection: header. */ - if (strConnection.size()>0 && strListIsMember(&strConnection, e->name.unsafeBuf(), ',')) { + if (strConnection.size()>0 && strListIsMember(&strConnection, e->name.termedBuf(), ',')) { debugs(11, 2, "'" << e->name << "' header cropped by Connection: definition"); return; } === modified file 'src/peer_digest.cc' --- src/peer_digest.cc 2009-01-29 14:50:26 +0000 +++ src/peer_digest.cc 2009-02-12 10:46:08 +0000 @@ -231,7 +231,7 @@ { eventAdd("peerDigestCheck", peerDigestCheck, pd, (double) delay, 1); pd->times.next_check = squid_curtime + delay; - debugs(72, 3, "peerDigestSetCheck: will check peer " << pd->host.unsafeBuf() << " in " << delay << " secs"); + debugs(72, 3, "peerDigestSetCheck: will check peer " << pd->host << " in " << delay << " secs"); } /* @@ -241,10 +241,10 @@ peerDigestNotePeerGone(PeerDigest * pd) { if (pd->flags.requested) { - debugs(72, 2, "peerDigest: peer " << pd->host.unsafeBuf() << " gone, will destroy after fetch."); + debugs(72, 2, "peerDigest: peer " << pd->host << " gone, will destroy after fetch."); /* do nothing now, the fetching chain will notice and take action */ } else { - debugs(72, 2, "peerDigest: peer " << pd->host.unsafeBuf() << " is gone, destroying now."); + debugs(72, 2, "peerDigest: peer " << pd->host << " is gone, destroying now."); peerDigestDestroy(pd); } } @@ -279,7 +279,7 @@ /* per-peer limit */ if (req_time - pd->times.received < PeerDigestReqMinGap) { - debugs(72, 2, "peerDigestCheck: " << pd->host.unsafeBuf() << + debugs(72, 2, "peerDigestCheck: " << pd->host << ", avoiding close peer requests (" << (int) (req_time - pd->times.received) << " < " << (int) PeerDigestReqMinGap << " secs)."); @@ -289,7 +289,7 @@ /* global limit */ if (req_time - pd_last_req_time < GlobDigestReqMinGap) { - debugs(72, 2, "peerDigestCheck: " << pd->host.unsafeBuf() << + debugs(72, 2, "peerDigestCheck: " << pd->host << ", avoiding close requests (" << (int) (req_time - pd_last_req_time) << " < " << (int) GlobDigestReqMinGap << " secs)."); @@ -544,7 +544,7 @@ assert(reply); assert (reply->sline.status != 0); status = reply->sline.status; - debugs(72, 3, "peerDigestFetchReply: " << pd->host.unsafeBuf() << " status: " << status << + debugs(72, 3, "peerDigestFetchReply: " << pd->host << " status: " << status << ", expires: " << (long int) reply->expires << " (" << std::showpos << (int) (reply->expires - squid_curtime) << ")"); @@ -634,7 +634,7 @@ assert (fetch->entry->getReply()->sline.status != 0); if (fetch->entry->getReply()->sline.status != HTTP_OK) { - debugs(72, 1, "peerDigestSwapInHeaders: " << fetch->pd->host.unsafeBuf() << + debugs(72, 1, "peerDigestSwapInHeaders: " << fetch->pd->host << " status " << fetch->entry->getReply()->sline.status << " got cached!"); @@ -762,7 +762,7 @@ #endif else - host = pd->host.unsafeBuf(); + host = pd->host.termedBuf(); } debugs(72, 6, step_name << ": peer " << host << ", offset: " << @@ -813,7 +813,7 @@ peerDigestFetchStop(DigestFetchState * fetch, char *buf, const char *reason) { assert(reason); - debugs(72, 2, "peerDigestFetchStop: peer " << fetch->pd->host.unsafeBuf() << ", reason: " << reason); + debugs(72, 2, "peerDigestFetchStop: peer " << fetch->pd->host << ", reason: " << reason); peerDigestReqFinish(fetch, buf, 1, 1, 1, reason, 0); } @@ -822,7 +822,7 @@ peerDigestFetchAbort(DigestFetchState * fetch, char *buf, const char *reason) { assert(reason); - debugs(72, 2, "peerDigestFetchAbort: peer " << fetch->pd->host.unsafeBuf() << ", reason: " << reason); + debugs(72, 2, "peerDigestFetchAbort: peer " << fetch->pd->host << ", reason: " << reason); peerDigestReqFinish(fetch, buf, 1, 1, 1, reason, 1); } @@ -872,7 +872,7 @@ peerDigestPDFinish(DigestFetchState * fetch, int pcb_valid, int err) { PeerDigest *pd = fetch->pd; - const char *host = pd->host.unsafeBuf(); + const char *host = pd->host.termedBuf(); pd->times.received = squid_curtime; pd->times.req_delay = fetch->resp_time; @@ -986,7 +986,7 @@ { StoreDigestCBlock cblock; int freed_size = 0; - const char *host = pd->host.unsafeBuf(); + const char *host = pd->host.termedBuf(); xmemcpy(&cblock, buf, sizeof(cblock)); /* network -> host conversions */ @@ -1080,7 +1080,7 @@ const int bit_util = cacheDigestBitUtil(pd->cd); if (bit_util > 65) { - debugs(72, 0, "Warning: " << pd->host.unsafeBuf() << + debugs(72, 0, "Warning: " << pd->host << " peer digest has too many bits on (" << bit_util << "%%)."); return 0; @@ -1106,7 +1106,7 @@ assert(pd); - const char *host = pd->host.unsafeBuf(); + const char *host = pd->host.termedBuf(); storeAppendPrintf(e, "\npeer digest from %s\n", host); cacheDigestGuessStatsReport(&pd->stats.guess, e, host); === modified file 'src/protos.h' --- src/protos.h 2009-02-08 00:02:47 +0000 +++ src/protos.h 2009-02-11 15:28:22 +0000 @@ -179,6 +179,7 @@ SQUIDCEXTERN void ftpStart(FwdState *); class HttpRequest; +class HttpReply; /// \ingroup ServerProtocolFTPAPI SQUIDCEXTERN const char *ftpUrlWith2f(HttpRequest *); @@ -255,7 +256,7 @@ class HttpHeaderFieldInfo; SQUIDCEXTERN HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs * attrs, int count); SQUIDCEXTERN void httpHeaderDestroyFieldsInfo(HttpHeaderFieldInfo * info, int count); -SQUIDCEXTERN http_hdr_type httpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * attrs, int end); +SQUIDCEXTERN http_hdr_type httpHeaderIdByName(const char *name, size_t name_len, const HttpHeaderFieldInfo * attrs, int end); SQUIDCEXTERN http_hdr_type httpHeaderIdByNameDef(const char *name, int name_len); SQUIDCEXTERN const char *httpHeaderNameById(int id); SQUIDCEXTERN int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive); === modified file 'src/store.cc' --- src/store.cc 2009-02-08 00:02:47 +0000 +++ src/store.cc 2009-02-12 10:46:08 +0000 @@ -696,9 +696,9 @@ #if X_ACCELERATOR_VARY vary = mem_obj->getReply()->header.getList(HDR_X_ACCELERATOR_VARY); - if (vary.unsafeBuf()) { + if (vary.defined()) { /* Again, we own this structure layout */ - rep->header.putStr(HDR_X_ACCELERATOR_VARY, vary.unsafeBuf()); + rep->header.putStr(HDR_X_ACCELERATOR_VARY, vary.termedBuf()); vary.clean(); } === modified file 'src/store_log.cc' --- src/store_log.cc 2009-01-29 14:50:26 +0000 +++ src/store_log.cc 2009-02-12 16:06:20 +0000 @@ -52,12 +52,17 @@ static Logfile *storelog = NULL; +static String str_unknown; + void storeLog(int tag, const StoreEntry * e) { MemObject *mem = e->mem_obj; HttpReply const *reply; + if (str_unknown.undefined()) + str_unknown="unknown"; //hack. Delay initialization as string doesn't support global variables.. + if (NULL == storelog) return; @@ -75,7 +80,10 @@ * Because if we print it before the swap file number, it'll break * the existing log format. */ - logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s %4d %9d %9d %9d %s %"PRId64"/%"PRId64" %s %s\n", + + String ctype=(reply->content_type.size() ? reply->content_type.termedBuf() : str_unknown); + + logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s %4d %9d %9d %9d " SQUIDSTRINGPH " %"PRId64"/%"PRId64" %s %s\n", (int) current_time.tv_sec, (int) current_time.tv_usec / 1000, storeLogTags[tag], @@ -86,7 +94,7 @@ (int) reply->date, (int) reply->last_modified, (int) reply->expires, - reply->content_type.size() ? reply->content_type.unsafeBuf() : "unknown", + SQUIDSTRINGPRINT(ctype), reply->content_length, e->contentLen(), RequestMethodStr(mem->method), === modified file 'src/tests/testEvent.cc' --- src/tests/testEvent.cc 2009-01-30 14:55:22 +0000 +++ src/tests/testEvent.cc 2009-02-11 15:28:22 +0000 @@ -97,7 +97,7 @@ /* loop over the strings, showing exactly where they differ (if at all) */ printf("Actual Text:\n"); /* TODO: these should really be just [] lookups, but String doesn't have those here yet. */ - for ( int i = 0; i < anEntry->_appended_text.size(); i++) { + for ( unsigned int i = 0; i < anEntry->_appended_text.size(); i++) { CPPUNIT_ASSERT( expect[i] ); CPPUNIT_ASSERT( anEntry->_appended_text[i] ); === modified file 'src/tests/testString.cc' --- src/tests/testString.cc 2008-05-27 14:01:49 +0000 +++ src/tests/testString.cc 2009-02-11 15:28:22 +0000 @@ -59,3 +59,11 @@ CPPUNIT_ASSERT(right.cmp("foo") < 0); CPPUNIT_ASSERT(right.cmp("foo", 1) < 0); } + +void testString::testSubstr() +{ + String s("0123456789"); + String check=s.substr(3,5); + String ref("34"); + CPPUNIT_ASSERT(check == ref); +} === modified file 'src/tests/testString.h' --- src/tests/testString.h 2007-05-29 19:31:36 +0000 +++ src/tests/testString.h 2009-02-09 15:47:31 +0000 @@ -14,6 +14,8 @@ CPPUNIT_TEST( testCmpDefault ); CPPUNIT_TEST( testCmpEmptyString ); CPPUNIT_TEST( testCmpNotEmptyDefault ); + CPPUNIT_TEST( testSubstr ); + CPPUNIT_TEST_SUITE_END(); public: @@ -23,6 +25,7 @@ void testCmpDefault(); void testCmpEmptyString(); void testCmpNotEmptyDefault(); + void testSubstr(); }; #endif === modified file 'src/url.cc' --- src/url.cc 2009-02-03 17:36:15 +0000 +++ src/url.cc 2009-02-12 16:06:20 +0000 @@ -439,9 +439,8 @@ return request->canonical; if (request->protocol == PROTO_URN) { - snprintf(urlbuf, MAX_URL, "urn:%.*s", - request->urlpath.size(), - request->urlpath.rawBuf()); + snprintf(urlbuf, MAX_URL, "urn:" SQUIDSTRINGPH, + SQUIDSTRINGPRINT(request->urlpath)); } else { /// \todo AYJ: this could use "if..else and method == METHOD_CONNECT" easier. switch (request->method.id()) { @@ -456,14 +455,13 @@ if (request->port != urlDefaultPort(request->protocol)) snprintf(portbuf, 32, ":%d", request->port); - snprintf(urlbuf, MAX_URL, "%s://%s%s%s%s%.*s", + snprintf(urlbuf, MAX_URL, "%s://%s%s%s%s" SQUIDSTRINGPH, ProtocolStr[request->protocol], request->login, *request->login ? "@" : null_string, request->GetHost(), portbuf, - request->urlpath.size(), - request->urlpath.rawBuf()); + SQUIDSTRINGPRINT(request->urlpath)); break; } @@ -485,8 +483,8 @@ char *t; if (request->protocol == PROTO_URN) { - snprintf(buf, MAX_URL, "urn:%.*s", - request->urlpath.size(), request->urlpath.rawBuf()); + snprintf(buf, MAX_URL, "urn:" SQUIDSTRINGPH, + SQUIDSTRINGPRINT(request->urlpath)); } else { /// \todo AYJ: this could use "if..else and method == METHOD_CONNECT" easier. switch (request->method.id()) { @@ -514,13 +512,12 @@ strcat(loginbuf, "@"); } - snprintf(buf, MAX_URL, "%s://%s%s%s%.*s", + snprintf(buf, MAX_URL, "%s://%s%s%s" SQUIDSTRINGPH, ProtocolStr[request->protocol], loginbuf, request->GetHost(), portbuf, - request->urlpath.size(), - request->urlpath.rawBuf()); + SQUIDSTRINGPRINT(request->urlpath)); /* * strip arguments AFTER a question-mark */ @@ -589,9 +586,8 @@ char *urlbuf = (char *)xmalloc(MAX_URL * sizeof(char)); if (req->protocol == PROTO_URN) { - snprintf(urlbuf, MAX_URL, "urn:%.*s", - req->urlpath.size(), - req->urlpath.rawBuf()); + snprintf(urlbuf, MAX_URL, "urn:" SQUIDSTRINGPH, + SQUIDSTRINGPRINT(req->urlpath)); return (urlbuf); } === modified file 'src/urn.cc' --- src/urn.cc 2009-02-03 17:36:15 +0000 +++ src/urn.cc 2009-02-12 11:17:16 +0000 @@ -57,7 +57,7 @@ char *getHost (String &urlpath); void setUriResFromRequest(HttpRequest *); bool RequestNeedsMenu(HttpRequest *r); - void updateRequestURL(HttpRequest *r, char const *newPath); + void updateRequestURL(HttpRequest *r, char const *newPath, const size_t newPath_len); void createUriResRequest (String &uri); virtual ~UrnState(); @@ -171,7 +171,7 @@ /** FIXME: this appears to be parsing the URL. *very* badly. */ /* a proper encapsulated URI/URL type needs to clear this up. */ - if ((p=urlpath.find(':')) != std::string::npos) { + if ((p=urlpath.find(':')) != String::npos) { result=xstrndup(urlpath.rawBuf(),p-1); } else { result = xstrndup(urlpath.rawBuf(),urlpath.size()); @@ -182,13 +182,16 @@ bool UrnState::RequestNeedsMenu(HttpRequest *r) { - return strncasecmp(r->urlpath.unsafeBuf(), "menu.", 5) == 0; + if (r->urlpath.size() < 5) + return false; + //now we're sure it's long enough + return strncasecmp(r->urlpath.rawBuf(), "menu.", 5) == 0; } void -UrnState::updateRequestURL(HttpRequest *r, char const *newPath) +UrnState::updateRequestURL(HttpRequest *r, char const *newPath, const size_t newPath_len) { - char *new_path = xstrdup (newPath); + char *new_path = xstrndup (newPath, newPath_len); r->urlpath = new_path; xfree(new_path); } @@ -198,7 +201,8 @@ { LOCAL_ARRAY(char, local_urlres, 4096); char *host = getHost (uri); - snprintf(local_urlres, 4096, "http://%s/uri-res/N2L?urn:%s", host, uri.unsafeBuf()); + snprintf(local_urlres, 4096, "http://%s/uri-res/N2L?urn:" SQUIDSTRINGPH, + host, SQUIDSTRINGPRINT(uri)); safe_free (host); safe_free (urlres); urlres = xstrdup (local_urlres); @@ -209,7 +213,7 @@ UrnState::setUriResFromRequest(HttpRequest *r) { if (RequestNeedsMenu(r)) { - updateRequestURL(r, r->urlpath.unsafeBuf() + 5); + updateRequestURL(r, r->urlpath.rawBuf() + 5, r->urlpath.size() - 5 ); flags.force_menu = 1; } === modified file 'src/whois.cc' --- src/whois.cc 2009-01-29 14:50:26 +0000 +++ src/whois.cc 2009-02-12 11:17:16 +0000 @@ -98,7 +98,8 @@ buf = (char *)xmalloc(l); - snprintf(buf, l, "%s\r\n", p->request->urlpath.unsafeBuf() + 1); + String str_print=p->request->urlpath.substr(1,p->request->urlpath.size()); + snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print)); comm_write(fd, buf, strlen(buf), whoisWriteComplete, p, NULL); comm_read(fd, p->buf, BUFSIZ, whoisReadReply, p); # Begin bundle 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 H/8XckU4UJCQWE1o