]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/stringbuf.c
* more testcoverage
[citadel.git] / libcitadel / lib / stringbuf.c
index 89d93fa881e72143a8f745993913d04ff0525532..c41be76fcdd2d4482827ac8da341b89168019001 100644 (file)
@@ -29,6 +29,24 @@ int BaseStrBufSize = 64;
 
 const char *StrBufNOTNULL = ((char*) NULL) - 1;
 
+const char HexList[256][3] = {
+"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
+"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
+"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
+"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
+"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
+"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
+"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
+"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
+"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
+"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
+"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
+"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
+"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
+"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
+"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
+"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"};
+
 /**
  * @defgroup StrBuf Stringbuffer, A class for manipulating strings with dynamic buffers
  * StrBuf is a versatile class, aiding the handling of dynamic strings
@@ -503,7 +521,7 @@ char *SmashStrBuf (StrBuf **SmashMe)
 {
        char *Ret;
 
-       if (*SmashMe == NULL)
+       if ((SmashMe == NULL) || (*SmashMe == NULL))
                return NULL;
 #ifdef SIZE_DEBUG
        if (hFreeDbglog == -1){
@@ -739,10 +757,8 @@ void StrBufUrlescAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn)
 {
        const char *pch, *pche;
        char *pt, *pte;
-       int b, c, len;
-       const char ec[] = " +#&;`'|*?-~<>^()[]{}/$\"\\";
-       int eclen = sizeof(ec) -1;
-
+       int len;
+       
        if (((In == NULL) && (PlainIn == NULL)) || (OutBuf == NULL) )
                return;
        if (PlainIn != NULL) {
@@ -768,24 +784,25 @@ void StrBufUrlescAppend(StrBuf *OutBuf, const StrBuf *In, const char *PlainIn)
                        pte = OutBuf->buf + OutBuf->BufSize - 4; /**< we max append 3 chars at once plus the \0 */
                        pt = OutBuf->buf + OutBuf->BufUsed;
                }
-               
-               c = 0;
-               for (b = 0; b < eclen; ++b) {
-                       if (*pch == ec[b]) {
-                               c = 1;
-                               b += eclen;
-                       }
-               }
-               if (c == 1) {
-                       sprintf(pt,"%%%02X", *pch);
+
+               if((*pch >= 'a' && *pch <= 'z') ||
+                  (*pch >= '@' && *pch <= 'Z') || /* @ A-Z */
+                  (*pch >= '0' && *pch <= ':') || /* 0-9 : */
+                  (*pch == '!') || (*pch == '_') || 
+                  (*pch == ',') || (*pch == '.') || 
+                  (*pch == ','))
+               {
+                       *(pt++) = *(pch++);
+                       OutBuf->BufUsed++;
+               }                       
+               else {
+                       *pt = '%';
+                       *(pt + 1) = HexList[(unsigned char)*pch][0];
+                       *(pt + 2) = HexList[(unsigned char)*pch][1];
                        pt += 3;
                        OutBuf->BufUsed += 3;
                        pch ++;
                }
-               else {
-                       *(pt++) = *(pch++);
-                       OutBuf->BufUsed++;
-               }
        }
        *pt = '\0';
 }
@@ -1209,21 +1226,24 @@ long StrHtmlEcmaEscAppend(StrBuf *Target, const StrBuf *Source, const char *Plai
                        Target->BufUsed += 2;
                }
                else {
-                       if (IsUtf8Sequence != 0) {
-                               IsUtf8Sequence --;
+                       if (((unsigned char)*aptr) >= 0x20)
+                       {
+                               IsUtf8Sequence =  Ctdl_GetUtf8SequenceLength(aptr, eiptr);
+                               
                                *bptr = *aptr;
-                               bptr++;
                                Target->BufUsed ++;
-                       }
-                       else {
-                               if (*aptr >= 0x20)
-                               {
-                                       IsUtf8Sequence =  Ctdl_GetUtf8SequenceLength(aptr, eiptr);
-
+                               while (IsUtf8Sequence > 1){
+                                       if(bptr + IsUtf8Sequence >= eptr) {
+                                               IncreaseBuf(Target, 1, -1);
+                                               eptr = Target->buf + Target->BufSize - 11; /* our biggest unit to put in...  */
+                                               bptr = Target->buf + Target->BufUsed - 1;
+                                       }
+                                       bptr++; aptr++;
+                                       IsUtf8Sequence --;
                                        *bptr = *aptr;
-                                       bptr++;
                                        Target->BufUsed ++;
                                }
+                               bptr++;
                        }
 
                }
@@ -1418,8 +1438,8 @@ int StrBufRemove_token(StrBuf *Source, int parmnum, char separator)
        /* Find desired @parameter */
        end = Source->buf + Source->BufUsed;
        d = Source->buf;
-       while ((count < parmnum) &&
-              (d <= end))
+       while ((d <= end) && 
+              (count < parmnum))
        {
                /* End of string, bail! */
                if (!*d) {
@@ -1436,8 +1456,8 @@ int StrBufRemove_token(StrBuf *Source, int parmnum, char separator)
 
        /* Find next @parameter */
        s = d;
-       while ((*s && *s != separator) &&
-              (s <= end))
+       while ((s <= end) && 
+              (*s && *s != separator))
        {
                s++;
        }
@@ -1446,16 +1466,20 @@ int StrBufRemove_token(StrBuf *Source, int parmnum, char separator)
        ReducedBy = d - s;
 
        /* Hack and slash */
-       if (*s) {
+       if (s >= end) {
+               return 0;
+       }
+       else if (*s) {
                memmove(d, s, Source->BufUsed - (s - Source->buf));
                Source->BufUsed += ReducedBy;
+               Source->buf[Source->BufUsed] = '\0';
        }
        else if (d == Source->buf) {
                *d = 0;
                Source->BufUsed = 0;
        }
        else {
-               *--d = 0;
+               *--d = '\0';
                Source->BufUsed += ReducedBy;
        }
        /*
@@ -2020,6 +2044,7 @@ int StrBufTCP_read_buffered_line(StrBuf *Line,
 
 }
 
+static const char *ErrRBLF_PreConditionFailed="StrBufTCP_read_buffered_line_fast: Wrong arguments or invalid Filedescriptor";
 static const char *ErrRBLF_SelectFailed="StrBufTCP_read_buffered_line_fast: Select failed without reason";
 static const char *ErrRBLF_NotEnoughSentFromServer="StrBufTCP_read_buffered_line_fast: No complete line was sent from peer";
 /**
@@ -2053,6 +2078,17 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
        int IsNonBlock;
        struct timeval tv;
        
+       if ((Line == NULL) ||
+           (Pos == NULL) ||
+           (IOBuf == NULL) ||
+           (*fd == -1))
+       {
+               if (Pos != NULL)
+                       *Pos = NULL;
+               *Error = ErrRBLF_PreConditionFailed;
+               return -1;
+       }
+
        pos = *Pos;
        if ((IOBuf->BufUsed > 0) && 
            (pos != NULL) && 
@@ -2087,6 +2123,7 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
        
        if (IOBuf->BufSize - IOBuf->BufUsed < 10) {
                IncreaseBuf(IOBuf, 1, -1);
+               *Pos = NULL;
        }
 
        fdflags = fcntl(*fd, F_GETFL);
@@ -2131,6 +2168,7 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
                        IOBuf->buf[IOBuf->BufUsed] = '\0';
                        if (IOBuf->BufUsed + 10 > IOBuf->BufSize) {
                                IncreaseBuf(IOBuf, 1, -1);
+                               *Pos = NULL;
                        }
                        
                        pche = IOBuf->buf + IOBuf->BufUsed;
@@ -2157,6 +2195,7 @@ int StrBufTCP_read_buffered_line_fast(StrBuf *Line,
 
 }
 
+static const char *ErrRBLF_BLOBPreConditionFailed="StrBufReadBLOB: Wrong arguments or invalid Filedescriptor";
 /**
  * @ingroup StrBuf_IO
  * @brief Input binary data from socket
@@ -2178,8 +2217,12 @@ int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **E
        int IsNonBlock;
        struct timeval tv;
        fd_set rfds;
+
        if ((Buf == NULL) || (*fd == -1))
+       {
+               *Error = ErrRBLF_BLOBPreConditionFailed;
                return -1;
+       }
        if (!append)
                FlushStrBuf(Buf);
        if (Buf->BufUsed + nBytes >= Buf->BufSize)
@@ -2232,6 +2275,7 @@ int StrBufReadBLOB(StrBuf *Buf, int *fd, int append, long nBytes, const char **E
        return nRead;
 }
 
+const char *ErrRBB_BLOBFPreConditionFailed = "StrBufReadBLOBBuffered: to many selects; aborting.";
 const char *ErrRBB_too_many_selects = "StrBufReadBLOBBuffered: to many selects; aborting.";
 /**
  * @ingroup StrBuf_BufferedIO
@@ -2273,7 +2317,13 @@ int StrBufReadBLOBBuffered(StrBuf *Blob,
        int nSuccessLess;
 
        if ((Blob == NULL) || (*fd == -1) || (IOBuf == NULL) || (Pos == NULL))
+       {
+               if (*Pos != NULL)
+                       *Pos = NULL;
+               *Error = ErrRBB_BLOBFPreConditionFailed;
                return -1;
+       }
+
        if (!append)
                FlushStrBuf(Blob);
        if (Blob->BufUsed + nBytes >= Blob->BufSize) 
@@ -2315,6 +2365,7 @@ int StrBufReadBLOBBuffered(StrBuf *Blob,
        }
 
        FlushStrBuf(IOBuf);
+       *Pos = NULL;
        if (IOBuf->BufSize < nBytes - nRead)
                IncreaseBuf(IOBuf, 0, nBytes - nRead);
        ptr = IOBuf->buf;
@@ -3328,7 +3379,7 @@ static inline int Ctdl_GetUtf8SequenceLength(const char *CharS, const char *Char
                test = test << 1;
                n ++;
        }
-       if ((n > 6) || ((CharE - CharS) > n))
+       if ((n > 6) || ((CharE - CharS) < n))
                n = 1;
        return n;
 }
@@ -3364,14 +3415,13 @@ long StrBuf_Utf8StrLen(StrBuf *Buf)
        while ((aptr < eptr) && (*aptr != '\0')) {
                if (Ctdl_IsUtf8SequenceStart(*aptr)){
                        m = Ctdl_GetUtf8SequenceLength(aptr, eptr);
-                       while ((aptr < eptr) && (m-- > 0) && (*aptr++ != '\0'))
-                               n ++;
+                       while ((aptr < eptr) && (*aptr++ != '\0')&& (m-- > 0) );
+                       n ++;
                }
                else {
                        n++;
                        aptr++;
                }
-                       
        }
        return n;
 }
@@ -3393,8 +3443,8 @@ long StrBuf_Utf8StrCut(StrBuf *Buf, int maxlen)
        while ((aptr < eptr) && (*aptr != '\0')) {
                if (Ctdl_IsUtf8SequenceStart(*aptr)){
                        m = Ctdl_GetUtf8SequenceLength(aptr, eptr);
-                       while ((m-- > 0) && (*aptr++ != '\0'))
-                               n ++;
+                       while ((*aptr++ != '\0') && (m-- > 0));
+                       n ++;
                }
                else {
                        n++;
@@ -3472,3 +3522,4 @@ int StrBufSipLine(StrBuf *LineBuf, StrBuf *Buf, const char **Ptr)
 
        return Buf->BufUsed - (ptr - Buf->buf);
 }
+