diff --git a/bstrlib.c b/bstrlib.c index f0dea7c..eb92ceb 100644 --- a/bstrlib.c +++ b/bstrlib.c @@ -1,7 +1,7 @@ /* * This source file is part of the bstring string library. This code was - * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source - * license and the GPL. Refer to the accompanying documentation for details + * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source + * license and the GPL. Refer to the accompanying documentation for details * on usage and license. */ @@ -97,7 +97,7 @@ static int snapUpSize (int i) { */ int balloc (bstring b, int olen) { int len; - if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 || + if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen || olen <= 0) { return BSTR_ERR; } @@ -118,7 +118,7 @@ int balloc (bstring b, int olen) { x = (unsigned char *) bstr__realloc (b->data, (size_t) len); if (x == NULL) { - /* Since we failed, try allocating the tighest possible + /* Since we failed, try allocating the tighest possible allocation */ if (NULL == (x = (unsigned char *) bstr__realloc (b->data, (size_t) (len = olen)))) { @@ -133,7 +133,7 @@ int balloc (bstring b, int olen) { if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) { - /* Perhaps there is no available memory for the two + /* Perhaps there is no available memory for the two allocations to be in memory at once */ goto reallocStrategy; @@ -160,7 +160,7 @@ int balloc (bstring b, int olen) { int ballocmin (bstring b, int len) { unsigned char * s; - if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 || + if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 || b->mlen < b->slen || len <= 0) { return BSTR_ERR; } @@ -208,7 +208,7 @@ size_t j; /* bstring bfromcstralloc (int mlen, const char * str) * * Create a bstring which contains the contents of the '\0' terminated char * - * buffer str. The memory buffer backing the string is at least len + * buffer str. The memory buffer backing the string is at least len * characters in length. */ bstring bfromcstralloc (int mlen, const char * str) { @@ -237,7 +237,7 @@ size_t j; /* bstring blk2bstr (const void * blk, int len) * - * Create a bstring which contains the content of the block blk of length + * Create a bstring which contains the content of the block blk of length * len. */ bstring blk2bstr (const void * blk, int len) { @@ -268,9 +268,9 @@ int i; /* char * bstr2cstr (const_bstring s, char z) * - * Create a '\0' terminated char * buffer which is equal to the contents of - * the bstring s, except that any contained '\0' characters are converted - * to the character in z. This returned value should be freed with a + * Create a '\0' terminated char * buffer which is equal to the contents of + * the bstring s, except that any contained '\0' characters are converted + * to the character in z. This returned value should be freed with a * bcstrfree () call, by the calling application. */ char * bstr2cstr (const_bstring b, char z) { @@ -294,12 +294,12 @@ char * r; /* int bcstrfree (char * s) * * Frees a C-string generated by bstr2cstr (). This is normally unnecessary - * since it just wraps a call to bstr__free (), however, if bstr__alloc () - * and bstr__free () have been redefined as a macros within the bstrlib - * module (via defining them in memdbg.h after defining - * BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std - * library functions, then this allows a correct way of freeing the memory - * that allows higher level code to be independent from these macro + * since it just wraps a call to bstr__free (), however, if bstr__alloc () + * and bstr__free () have been redefined as a macros within the bstrlib + * module (via defining them in memdbg.h after defining + * BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std + * library functions, then this allows a correct way of freeing the memory + * that allows higher level code to be independent from these macro * redefinitions. */ int bcstrfree (char * s) { @@ -343,7 +343,7 @@ bstring aux = (bstring) b1; } /* int bconchar (bstring b, char c) -/ * + * * Concatenate the single character c to the bstring b. */ int bconchar (bstring b, char c) { @@ -454,8 +454,8 @@ int bassign (bstring a, const_bstring b) { if (balloc (a, b->slen) != BSTR_OK) return BSTR_ERR; bstr__memmove (a->data, b->data, b->slen); } else { - if (a == NULL || a->data == NULL || a->mlen < a->slen || - a->slen < 0 || a->mlen == 0) + if (a == NULL || a->data == NULL || a->mlen < a->slen || + a->slen < 0 || a->mlen == 0) return BSTR_ERR; } a->data[b->slen] = (unsigned char) '\0'; @@ -465,8 +465,8 @@ int bassign (bstring a, const_bstring b) { /* int bassignmidstr (bstring a, const_bstring b, int left, int len) * - * Overwrite the string a with the middle of contents of string b - * starting from position left and running for a length len. left and + * Overwrite the string a with the middle of contents of string b + * starting from position left and running for a length len. left and * len are clamped to the ends of b as with the function bmidstr. */ int bassignmidstr (bstring a, const_bstring b, int left, int len) { @@ -497,15 +497,15 @@ int bassignmidstr (bstring a, const_bstring b, int left, int len) { /* int bassigncstr (bstring a, const char * str) * - * Overwrite the string a with the contents of char * string str. Note that - * the bstring a must be a well defined and writable bstring. If an error + * Overwrite the string a with the contents of char * string str. Note that + * the bstring a must be a well defined and writable bstring. If an error * occurs BSTR_ERR is returned however a may be partially overwritten. */ int bassigncstr (bstring a, const char * str) { int i; size_t len; if (a == NULL || a->data == NULL || a->mlen < a->slen || - a->slen < 0 || a->mlen == 0 || NULL == str) + a->slen < 0 || a->mlen == 0 || NULL == str) return BSTR_ERR; for (i=0; i < a->mlen; i++) { @@ -526,13 +526,13 @@ size_t len; /* int bassignblk (bstring a, const void * s, int len) * - * Overwrite the string a with the contents of the block (s, len). Note that - * the bstring a must be a well defined and writable bstring. If an error + * Overwrite the string a with the contents of the block (s, len). Note that + * the bstring a must be a well defined and writable bstring. If an error * occurs BSTR_ERR is returned and a is not overwritten. */ int bassignblk (bstring a, const void * s, int len) { if (a == NULL || a->data == NULL || a->mlen < a->slen || - a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1) + a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1) return BSTR_ERR; if (len + 1 > a->mlen && 0 > balloc (a, len + 1)) return BSTR_ERR; bBlockCopy (a->data, s, (size_t) len); @@ -589,17 +589,17 @@ int i, len; /* int bstricmp (const_bstring b0, const_bstring b1) * - * Compare two strings without differentiating between case. The return - * value is the difference of the values of the characters where the two - * strings first differ after lower case transformation, otherwise 0 is - * returned indicating that the strings are equal. If the lengths are - * different, then a difference from 0 is given, but if the first extra + * Compare two strings without differentiating between case. The return + * value is the difference of the values of the characters where the two + * strings first differ after lower case transformation, otherwise 0 is + * returned indicating that the strings are equal. If the lengths are + * different, then a difference from 0 is given, but if the first extra * character is '\0', then it is taken to be the value UCHAR_MAX+1. */ int bstricmp (const_bstring b0, const_bstring b1) { int i, v, n; - if (bdata (b0) == NULL || b0->slen < 0 || + if (bdata (b0) == NULL || b0->slen < 0 || bdata (b1) == NULL || b1->slen < 0) return SHRT_MIN; if ((n = b0->slen) > b1->slen) n = b1->slen; else if (b0->slen == b1->slen && b0->data == b1->data) return BSTR_OK; @@ -629,14 +629,14 @@ int i, v, n; * characters. If the position where the two strings first differ is * before the nth position, the return value is the difference of the values * of the characters, otherwise 0 is returned. If the lengths are different - * and less than n characters, then a difference from 0 is given, but if the - * first extra character is '\0', then it is taken to be the value + * and less than n characters, then a difference from 0 is given, but if the + * first extra character is '\0', then it is taken to be the value * UCHAR_MAX+1. */ int bstrnicmp (const_bstring b0, const_bstring b1, int n) { int i, v, m; - if (bdata (b0) == NULL || b0->slen < 0 || + if (bdata (b0) == NULL || b0->slen < 0 || bdata (b1) == NULL || b1->slen < 0 || n < 0) return SHRT_MIN; m = n; if (m > b0->slen) m = b0->slen; @@ -665,16 +665,16 @@ int i, v, m; /* int biseqcaseless (const_bstring b0, const_bstring b1) * - * Compare two strings for equality without differentiating between case. - * If the strings differ other than in case, 0 is returned, if the strings - * are the same, 1 is returned, if there is an error, -1 is returned. If - * the length of the strings are different, this function is O(1). '\0' + * Compare two strings for equality without differentiating between case. + * If the strings differ other than in case, 0 is returned, if the strings + * are the same, 1 is returned, if there is an error, -1 is returned. If + * the length of the strings are different, this function is O(1). '\0' * termination characters are not treated in any special way. */ int biseqcaseless (const_bstring b0, const_bstring b1) { int i, n; - if (bdata (b0) == NULL || b0->slen < 0 || + if (bdata (b0) == NULL || b0->slen < 0 || bdata (b1) == NULL || b1->slen < 0) return BSTR_ERR; if (b0->slen != b1->slen) return BSTR_OK; if (b0->data == b1->data || b0->slen == 0) return 1; @@ -689,11 +689,11 @@ int i, n; /* int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) * - * Compare beginning of string b0 with a block of memory of length len + * Compare beginning of string b0 with a block of memory of length len * without differentiating between case for equality. If the beginning of b0 - * differs from the memory block other than in case (or if b0 is too short), - * 0 is returned, if the strings are the same, 1 is returned, if there is an - * error, -1 is returned. '\0' characters are not treated in any special + * differs from the memory block other than in case (or if b0 is too short), + * 0 is returned, if the strings are the same, 1 is returned, if there is an + * error, -1 is returned. '\0' characters are not treated in any special * way. */ int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) { @@ -706,7 +706,7 @@ int i; for (i = 0; i < len; i ++) { if (b0->data[i] != ((const unsigned char *) blk)[i]) { - if (downcase (b0->data[i]) != + if (downcase (b0->data[i]) != downcase (((const unsigned char *) blk)[i])) return 0; } } @@ -786,8 +786,8 @@ int i, j; /* int biseq (const_bstring b0, const_bstring b1) * - * Compare the string b0 and b1. If the strings differ, 0 is returned, if - * the strings are the same, 1 is returned, if there is an error, -1 is + * Compare the string b0 and b1. If the strings differ, 0 is returned, if + * the strings are the same, 1 is returned, if there is an error, -1 is * returned. If the length of the strings are different, this function is * O(1). '\0' termination characters are not treated in any special way. */ @@ -801,10 +801,10 @@ int biseq (const_bstring b0, const_bstring b1) { /* int bisstemeqblk (const_bstring b0, const void * blk, int len) * - * Compare beginning of string b0 with a block of memory of length len for - * equality. If the beginning of b0 differs from the memory block (or if b0 - * is too short), 0 is returned, if the strings are the same, 1 is returned, - * if there is an error, -1 is returned. '\0' characters are not treated in + * Compare beginning of string b0 with a block of memory of length len for + * equality. If the beginning of b0 differs from the memory block (or if b0 + * is too short), 0 is returned, if the strings are the same, 1 is returned, + * if there is an error, -1 is returned. '\0' characters are not treated in * any special way. */ int bisstemeqblk (const_bstring b0, const void * blk, int len) { @@ -823,13 +823,13 @@ int i; /* int biseqcstr (const_bstring b, const char *s) * - * Compare the bstring b and char * string s. The C string s must be '\0' - * terminated at exactly the length of the bstring b, and the contents - * between the two must be identical with the bstring b with no '\0' - * characters for the two contents to be considered equal. This is - * equivalent to the condition that their current contents will be always be - * equal when comparing them in the same format after converting one or the - * other. If the strings are equal 1 is returned, if they are unequal 0 is + * Compare the bstring b and char * string s. The C string s must be '\0' + * terminated at exactly the length of the bstring b, and the contents + * between the two must be identical with the bstring b with no '\0' + * characters for the two contents to be considered equal. This is + * equivalent to the condition that their current contents will be always be + * equal when comparing them in the same format after converting one or the + * other. If the strings are equal 1 is returned, if they are unequal 0 is * returned and if there is a detectable error BSTR_ERR is returned. */ int biseqcstr (const_bstring b, const char * s) { @@ -843,22 +843,22 @@ int i; /* int biseqcstrcaseless (const_bstring b, const char *s) * - * Compare the bstring b and char * string s. The C string s must be '\0' - * terminated at exactly the length of the bstring b, and the contents - * between the two must be identical except for case with the bstring b with - * no '\0' characters for the two contents to be considered equal. This is - * equivalent to the condition that their current contents will be always be - * equal ignoring case when comparing them in the same format after - * converting one or the other. If the strings are equal, except for case, - * 1 is returned, if they are unequal regardless of case 0 is returned and + * Compare the bstring b and char * string s. The C string s must be '\0' + * terminated at exactly the length of the bstring b, and the contents + * between the two must be identical except for case with the bstring b with + * no '\0' characters for the two contents to be considered equal. This is + * equivalent to the condition that their current contents will be always be + * equal ignoring case when comparing them in the same format after + * converting one or the other. If the strings are equal, except for case, + * 1 is returned, if they are unequal regardless of case 0 is returned and * if there is a detectable error BSTR_ERR is returned. */ int biseqcstrcaseless (const_bstring b, const char * s) { int i; if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR; for (i=0; i < b->slen; i++) { - if (s[i] == '\0' || - (b->data[i] != (unsigned char) s[i] && + if (s[i] == '\0' || + (b->data[i] != (unsigned char) s[i] && downcase (b->data[i]) != (unsigned char) downcase (s[i]))) return BSTR_OK; } @@ -867,16 +867,16 @@ int i; /* int bstrcmp (const_bstring b0, const_bstring b1) * - * Compare the string b0 and b1. If there is an error, SHRT_MIN is returned, - * otherwise a value less than or greater than zero, indicating that the - * string pointed to by b0 is lexicographically less than or greater than - * the string pointed to by b1 is returned. If the the string lengths are - * unequal but the characters up until the length of the shorter are equal - * then a value less than, or greater than zero, indicating that the string - * pointed to by b0 is shorter or longer than the string pointed to by b1 is - * returned. 0 is returned if and only if the two strings are the same. If + * Compare the string b0 and b1. If there is an error, SHRT_MIN is returned, + * otherwise a value less than or greater than zero, indicating that the + * string pointed to by b0 is lexicographically less than or greater than + * the string pointed to by b1 is returned. If the the string lengths are + * unequal but the characters up until the length of the shorter are equal + * then a value less than, or greater than zero, indicating that the string + * pointed to by b0 is shorter or longer than the string pointed to by b1 is + * returned. 0 is returned if and only if the two strings are the same. If * the length of the strings are different, this function is O(n). Like its - * standard C library counter part strcmp, the comparison does not proceed + * standard C library counter part strcmp, the comparison does not proceed * past any '\0' termination characters encountered. */ int bstrcmp (const_bstring b0, const_bstring b1) { @@ -901,12 +901,12 @@ int i, v, n; /* int bstrncmp (const_bstring b0, const_bstring b1, int n) * - * Compare the string b0 and b1 for at most n characters. If there is an - * error, SHRT_MIN is returned, otherwise a value is returned as if b0 and + * Compare the string b0 and b1 for at most n characters. If there is an + * error, SHRT_MIN is returned, otherwise a value is returned as if b0 and * b1 were first truncated to at most n characters then bstrcmp was called - * with these new strings are paremeters. If the length of the strings are - * different, this function is O(n). Like its standard C library counter - * part strcmp, the comparison does not proceed past any '\0' termination + * with these new strings are paremeters. If the length of the strings are + * different, this function is O(n). Like its standard C library counter + * part strcmp, the comparison does not proceed past any '\0' termination * characters encountered. */ int bstrncmp (const_bstring b0, const_bstring b1, int n) { @@ -936,7 +936,7 @@ int i, v, m; * * Create a bstring which is the substring of b starting from position left * and running for a length len (clamped by the end of the bstring b.) If - * b is detectably invalid, then NULL is returned. The section described + * b is detectably invalid, then NULL is returned. The section described * by (left, len) is clamped to the boundaries of b. */ bstring bmidstr (const_bstring b, int left, int len) { @@ -956,9 +956,9 @@ bstring bmidstr (const_bstring b, int left, int len) { /* int bdelete (bstring b, int pos, int len) * - * Removes characters from pos to pos+len-1 inclusive and shifts the tail of - * the bstring starting from pos+len to pos. len must be positive for this - * call to have any effect. The section of the string described by (pos, + * Removes characters from pos to pos+len-1 inclusive and shifts the tail of + * the bstring starting from pos+len to pos. len must be positive for this + * call to have any effect. The section of the string described by (pos, * len) is clamped to boundaries of the bstring b. */ int bdelete (bstring b, int pos, int len) { @@ -968,15 +968,15 @@ int bdelete (bstring b, int pos, int len) { pos = 0; } - if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 || - b->mlen < b->slen || b->mlen <= 0) + if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 || + b->mlen < b->slen || b->mlen <= 0) return BSTR_ERR; if (len > 0 && pos < b->slen) { if (pos + len >= b->slen) { b->slen = pos; } else { bBlockCopy ((char *) (b->data + pos), - (char *) (b->data + pos + len), + (char *) (b->data + pos + len), b->slen - (pos+len)); b->slen -= len; } @@ -989,7 +989,7 @@ int bdelete (bstring b, int pos, int len) { * * Free up the bstring. Note that if b is detectably invalid or not writable * then no action is performed and BSTR_ERR is returned. Like a freed memory - * allocation, dereferences, writes or any other action on b after it has + * allocation, dereferences, writes or any other action on b after it has * been bdestroyed is undefined. */ int bdestroy (bstring b) { @@ -999,7 +999,7 @@ int bdestroy (bstring b) { bstr__free (b->data); - /* In case there is any stale usage, there is one more chance to + /* In case there is any stale usage, there is one more chance to notice this error. */ b->slen = -1; @@ -1012,11 +1012,11 @@ int bdestroy (bstring b) { /* int binstr (const_bstring b1, int pos, const_bstring b2) * - * Search for the bstring b2 in b1 starting from position pos, and searching - * forward. If it is found then return with the first position where it is - * found, otherwise return BSTR_ERR. Note that this is just a brute force - * string searcher that does not attempt clever things like the Boyer-Moore - * search algorithm. Because of this there are many degenerate cases where + * Search for the bstring b2 in b1 starting from position pos, and searching + * forward. If it is found then return with the first position where it is + * found, otherwise return BSTR_ERR. Note that this is just a brute force + * string searcher that does not attempt clever things like the Boyer-Moore + * search algorithm. Because of this there are many degenerate cases where * this can take much longer than it needs to. */ int binstr (const_bstring b1, int pos, const_bstring b2) { @@ -1099,11 +1099,11 @@ register int i; /* int binstrr (const_bstring b1, int pos, const_bstring b2) * - * Search for the bstring b2 in b1 starting from position pos, and searching - * backward. If it is found then return with the first position where it is - * found, otherwise return BSTR_ERR. Note that this is just a brute force - * string searcher that does not attempt clever things like the Boyer-Moore - * search algorithm. Because of this there are many degenerate cases where + * Search for the bstring b2 in b1 starting from position pos, and searching + * backward. If it is found then return with the first position where it is + * found, otherwise return BSTR_ERR. Note that this is just a brute force + * string searcher that does not attempt clever things like the Boyer-Moore + * search algorithm. Because of this there are many degenerate cases where * this can take much longer than it needs to. */ int binstrr (const_bstring b1, int pos, const_bstring b2) { @@ -1146,11 +1146,11 @@ unsigned char * d0, * d1; /* int binstrcaseless (const_bstring b1, int pos, const_bstring b2) * - * Search for the bstring b2 in b1 starting from position pos, and searching - * forward but without regard to case. If it is found then return with the - * first position where it is found, otherwise return BSTR_ERR. Note that - * this is just a brute force string searcher that does not attempt clever - * things like the Boyer-Moore search algorithm. Because of this there are + * Search for the bstring b2 in b1 starting from position pos, and searching + * forward but without regard to case. If it is found then return with the + * first position where it is found, otherwise return BSTR_ERR. Note that + * this is just a brute force string searcher that does not attempt clever + * things like the Boyer-Moore search algorithm. Because of this there are * many degenerate cases where this can take much longer than it needs to. */ int binstrcaseless (const_bstring b1, int pos, const_bstring b2) { @@ -1194,11 +1194,11 @@ unsigned char * d0, * d1; /* int binstrrcaseless (const_bstring b1, int pos, const_bstring b2) * - * Search for the bstring b2 in b1 starting from position pos, and searching - * backward but without regard to case. If it is found then return with the - * first position where it is found, otherwise return BSTR_ERR. Note that - * this is just a brute force string searcher that does not attempt clever - * things like the Boyer-Moore search algorithm. Because of this there are + * Search for the bstring b2 in b1 starting from position pos, and searching + * backward but without regard to case. If it is found then return with the + * first position where it is found, otherwise return BSTR_ERR. Note that + * this is just a brute force string searcher that does not attempt clever + * things like the Boyer-Moore search algorithm. Because of this there are * many degenerate cases where this can take much longer than it needs to. */ int binstrrcaseless (const_bstring b1, int pos, const_bstring b2) { @@ -1242,7 +1242,7 @@ unsigned char * d0, * d1; /* int bstrchrp (const_bstring b, int c, int pos) * - * Search for the character c in b forwards from the position pos + * Search for the character c in b forwards from the position pos * (inclusive). */ int bstrchrp (const_bstring b, int c, int pos) { @@ -1256,12 +1256,12 @@ unsigned char * p; /* int bstrrchrp (const_bstring b, int c, int pos) * - * Search for the character c in b backwards from the position pos in string + * Search for the character c in b backwards from the position pos in string * (inclusive). */ int bstrrchrp (const_bstring b, int c, int pos) { int i; - + if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR; for (i=pos; i >= 0; i--) { if (b->data[i] == (unsigned char) c) return i; @@ -1319,8 +1319,8 @@ int i; /* int binchr (const_bstring b0, int pos, const_bstring b1); * - * Search for the first position in b0 starting from pos or after, in which - * one of the characters in b1 is found and return it. If such a position + * Search for the first position in b0 starting from pos or after, in which + * one of the characters in b1 is found and return it. If such a position * does not exist in b0, then BSTR_ERR is returned. */ int binchr (const_bstring b0, int pos, const_bstring b1) { @@ -1344,8 +1344,8 @@ int i; /* int binchrr (const_bstring b0, int pos, const_bstring b1); * - * Search for the last position in b0 no greater than pos, in which one of - * the characters in b1 is found and return it. If such a position does not + * Search for the last position in b0 no greater than pos, in which one of + * the characters in b1 is found and return it. If such a position does not * exist in b0, then BSTR_ERR is returned. */ int binchrr (const_bstring b0, int pos, const_bstring b1) { @@ -1360,13 +1360,13 @@ struct charField chrs; /* int bninchr (const_bstring b0, int pos, const_bstring b1); * - * Search for the first position in b0 starting from pos or after, in which - * none of the characters in b1 is found and return it. If such a position + * Search for the first position in b0 starting from pos or after, in which + * none of the characters in b1 is found and return it. If such a position * does not exist in b0, then BSTR_ERR is returned. */ int bninchr (const_bstring b0, int pos, const_bstring b1) { struct charField chrs; - if (pos < 0 || b0 == NULL || b0->data == NULL || + if (pos < 0 || b0 == NULL || b0->data == NULL || b0->slen <= pos) return BSTR_ERR; if (buildCharField (&chrs, b1) < 0) return BSTR_ERR; invertCharField (&chrs); @@ -1375,13 +1375,13 @@ struct charField chrs; /* int bninchrr (const_bstring b0, int pos, const_bstring b1); * - * Search for the last position in b0 no greater than pos, in which none of - * the characters in b1 is found and return it. If such a position does not + * Search for the last position in b0 no greater than pos, in which none of + * the characters in b1 is found and return it. If such a position does not * exist in b0, then BSTR_ERR is returned. */ int bninchrr (const_bstring b0, int pos, const_bstring b1) { struct charField chrs; - if (pos < 0 || b0 == NULL || b0->data == NULL || + if (pos < 0 || b0 == NULL || b0->data == NULL || b0->slen < pos) return BSTR_ERR; if (pos == b0->slen) pos--; if (buildCharField (&chrs, b1) < 0) return BSTR_ERR; @@ -1391,8 +1391,8 @@ struct charField chrs; /* int bsetstr (bstring b0, int pos, bstring b1, unsigned char fill) * - * Overwrite the string b0 starting at position pos with the string b1. If - * the position pos is past the end of b0, then the character "fill" is + * Overwrite the string b0 starting at position pos with the string b1. If + * the position pos is past the end of b0, then the character "fill" is * appended as necessary to make up the gap between the end of b0 and pos. * If b1 is NULL, it behaves as if it were a 0-length string. */ @@ -1401,7 +1401,7 @@ int d, newlen; ptrdiff_t pd; bstring aux = (bstring) b1; - if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data || + if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data || b0->mlen < b0->slen || b0->mlen <= 0) return BSTR_ERR; if (b1 != NULL && (b1->slen < 0 || b1->data == NULL)) return BSTR_ERR; @@ -1446,8 +1446,8 @@ bstring aux = (bstring) b1; /* int binsert (bstring b1, int pos, bstring b2, unsigned char fill) * - * Inserts the string b2 into b1 at position pos. If the position pos is - * past the end of b1, then the character "fill" is appended as necessary to + * Inserts the string b2 into b1 at position pos. If the position pos is + * past the end of b1, then the character "fill" is appended as necessary to * make up the gap between the end of b1 and pos. Unlike bsetstr, binsert * does not allow b2 to be NULL. */ @@ -1456,7 +1456,7 @@ int d, l; ptrdiff_t pd; bstring aux = (bstring) b2; - if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 || + if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return BSTR_ERR; /* Aliasing case */ @@ -1492,20 +1492,20 @@ bstring aux = (bstring) b2; return BSTR_OK; } -/* int breplace (bstring b1, int pos, int len, bstring b2, +/* int breplace (bstring b1, int pos, int len, bstring b2, * unsigned char fill) * * Replace a section of a string from pos for a length len with the string b2. * fill is used is pos > b1->slen. */ -int breplace (bstring b1, int pos, int len, const_bstring b2, +int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill) { int pl, ret; ptrdiff_t pd; bstring aux = (bstring) b2; - if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL || - b2 == NULL || b1->data == NULL || b2->data == NULL || + if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL || + b2 == NULL || b1->data == NULL || b2->data == NULL || b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return BSTR_ERR; @@ -1539,8 +1539,8 @@ bstring aux = (bstring) b2; return BSTR_OK; } -/* - * findreplaceengine is used to implement bfindreplace and +/* + * findreplaceengine is used to implement bfindreplace and * bfindreplacecaseless. It works by breaking the three cases of * expansion, reduction and replacement, and solving each of these * in the most efficient way possible. @@ -1559,8 +1559,8 @@ bstring auxf = (bstring) find; bstring auxr = (bstring) repl; if (b == NULL || b->data == NULL || find == NULL || - find->data == NULL || repl == NULL || repl->data == NULL || - pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen || + find->data == NULL || repl == NULL || repl->data == NULL || + pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen || b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return BSTR_ERR; if (pos > b->slen - find->slen) return BSTR_OK; @@ -1581,7 +1581,7 @@ bstring auxr = (bstring) repl; delta = auxf->slen - auxr->slen; - /* in-place replacement since find and replace strings are of equal + /* in-place replacement since find and replace strings are of equal length */ if (delta == 0) { while ((pos = instr (b, pos, auxf)) >= 0) { @@ -1619,15 +1619,15 @@ bstring auxr = (bstring) repl; return BSTR_OK; } - /* expanding replacement since find->slen < repl->slen. Its a lot - more complicated. This works by first finding all the matches and + /* expanding replacement since find->slen < repl->slen. Its a lot + more complicated. This works by first finding all the matches and storing them to a growable array, then doing at most one resize of the destination bstring and then performing the direct memory transfers - of the string segment pieces to form the final result. The growable - array of matches uses a deferred doubling reallocing strategy. What - this means is that it starts as a reasonably fixed sized auto array in - the hopes that many if not most cases will never need to grow this - array. But it switches as soon as the bounds of the array will be + of the string segment pieces to form the final result. The growable + array of matches uses a deferred doubling reallocing strategy. What + this means is that it starts as a reasonably fixed sized auto array in + the hopes that many if not most cases will never need to grow this + array. But it switches as soon as the bounds of the array will be exceeded. An extra find result is always appended to this array that corresponds to the end of the destination string, so slen is checked against mlen - 1 rather than mlen before resizing. @@ -1660,7 +1660,7 @@ bstring auxr = (bstring) repl; goto done; } } - + /* slen <= INITIAL_STATIC_INDEX_COUNT-1 or mlen-1 here. */ d[slen] = b->slen; @@ -1674,10 +1674,10 @@ bstring auxr = (bstring) repl; bstr__memmove (b->data + s + acc, b->data + s, l); } if (auxr->slen) { - bstr__memmove (b->data + s + acc - auxr->slen, + bstr__memmove (b->data + s + acc - auxr->slen, auxr->data, auxr->slen); } - acc += delta; + acc += delta; } b->data[b->slen] = (unsigned char) '\0'; } @@ -1690,7 +1690,7 @@ bstring auxr = (bstring) repl; return ret; } -/* int bfindreplace (bstring b, const_bstring find, const_bstring repl, +/* int bfindreplace (bstring b, const_bstring find, const_bstring repl, * int pos) * * Replace all occurrences of a find string with a replace string after a @@ -1700,10 +1700,10 @@ int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos) { return findreplaceengine (b, find, repl, pos, binstr); } -/* int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, +/* int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, * int pos) * - * Replace all occurrences of a find string, ignoring case, with a replace + * Replace all occurrences of a find string, ignoring case, with a replace * string after a given point in a bstring. */ int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos) { @@ -1712,9 +1712,9 @@ int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int /* int binsertch (bstring b, int pos, int len, unsigned char fill) * - * Inserts the character fill repeatedly into b at position pos for a - * length len. If the position pos is past the end of b, then the - * character "fill" is appended as necessary to make up the gap between the + * Inserts the character fill repeatedly into b at position pos for a + * length len. If the position pos is past the end of b, then the + * character "fill" is appended as necessary to make up the gap between the * end of b and the position pos + len. */ int binsertch (bstring b, int pos, int len, unsigned char fill) { @@ -1749,9 +1749,9 @@ int d, l, i; /* int bpattern (bstring b, int len) * - * Replicate the bstring, b in place, end to end repeatedly until it - * surpasses len characters, then chop the result to exactly len characters. - * This function operates in-place. The function will return with BSTR_ERR + * Replicate the bstring, b in place, end to end repeatedly until it + * surpasses len characters, then chop the result to exactly len characters. + * This function operates in-place. The function will return with BSTR_ERR * if b is NULL or of length 0, otherwise BSTR_OK is returned. */ int bpattern (bstring b, int len) { @@ -1772,8 +1772,8 @@ int i, d; /* int breada (bstring b, bNread readPtr, void * parm) * - * Use a finite buffer fread-like function readPtr to concatenate to the - * bstring b the entire contents of file-like source data in a roughly + * Use a finite buffer fread-like function readPtr to concatenate to the + * bstring b the entire contents of file-like source data in a roughly * efficient way. */ int breada (bstring b, bNread readPtr, void * parm) { @@ -1797,8 +1797,8 @@ int i, l, n; /* bstring bread (bNread readPtr, void * parm) * - * Use a finite buffer fread-like function readPtr to create a bstring - * filled with the entire contents of file-like source data in a roughly + * Use a finite buffer fread-like function readPtr to create a bstring + * filled with the entire contents of file-like source data in a roughly * efficient way. */ bstring bread (bNread readPtr, void * parm) { @@ -1813,15 +1813,15 @@ bstring buff; /* int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator) * - * Use an fgetc-like single character stream reading function (getcPtr) to + * Use an fgetc-like single character stream reading function (getcPtr) to * obtain a sequence of characters which are concatenated to the end of the - * bstring b. The stream read is terminated by the passed in terminator + * bstring b. The stream read is terminated by the passed in terminator * parameter. * - * If getcPtr returns with a negative number, or the terminator character - * (which is appended) is read, then the stream reading is halted and the + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the * function returns with a partial result in b. If there is an empty partial - * result, 1 is returned. If no characters are read, or there is some other + * result, 1 is returned. If no characters are read, or there is some other * detectable error, BSTR_ERR is returned. */ int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator) { @@ -1851,15 +1851,15 @@ int c, d, e; /* int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator) * - * Use an fgetc-like single character stream reading function (getcPtr) to + * Use an fgetc-like single character stream reading function (getcPtr) to * obtain a sequence of characters which are concatenated to the end of the - * bstring b. The stream read is terminated by the passed in terminator + * bstring b. The stream read is terminated by the passed in terminator * parameter. * - * If getcPtr returns with a negative number, or the terminator character - * (which is appended) is read, then the stream reading is halted and the - * function returns with a partial result concatentated to b. If there is - * an empty partial result, 1 is returned. If no characters are read, or + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * function returns with a partial result concatentated to b. If there is + * an empty partial result, 1 is returned. If no characters are read, or * there is some other detectable error, BSTR_ERR is returned. */ int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator) { @@ -1889,13 +1889,13 @@ int c, d, e; /* bstring bgets (bNgetc getcPtr, void * parm, char terminator) * - * Use an fgetc-like single character stream reading function (getcPtr) to - * obtain a sequence of characters which are concatenated into a bstring. + * Use an fgetc-like single character stream reading function (getcPtr) to + * obtain a sequence of characters which are concatenated into a bstring. * The stream read is terminated by the passed in terminator function. * - * If getcPtr returns with a negative number, or the terminator character - * (which is appended) is read, then the stream reading is halted and the - * result obtained thus far is returned. If no characters are read, or + * If getcPtr returns with a negative number, or the terminator character + * (which is appended) is read, then the stream reading is halted and the + * result obtained thus far is returned. If no characters are read, or * there is some other detectable error, NULL is returned. */ bstring bgets (bNgetc getcPtr, void * parm, char terminator) { @@ -1918,8 +1918,8 @@ struct bStream { /* struct bStream * bsopen (bNread readPtr, void * parm) * - * Wrap a given open stream (described by a fread compatible function - * pointer and stream handle) into an open bStream suitable for the bstring + * Wrap a given open stream (described by a fread compatible function + * pointer and stream handle) into an open bStream suitable for the bstring * library streaming functions. */ struct bStream * bsopen (bNread readPtr, void * parm) { @@ -1938,7 +1938,7 @@ struct bStream * s; /* int bsbufflength (struct bStream * s, int sz) * - * Set the length of the buffer used by the bStream. If sz is zero, the + * Set the length of the buffer used by the bStream. If sz is zero, the * length is not set. This function returns with the previous length. */ int bsbufflength (struct bStream * s, int sz) { @@ -1975,8 +1975,8 @@ void * parm; /* int bsreadlna (bstring r, struct bStream * s, char terminator) * * Read a bstring terminated by the terminator character or the end of the - * stream from the bStream (s) and return it into the parameter r. This - * function may read additional characters from the core stream that are not + * stream from the bStream (s) and return it into the parameter r. This + * function may read additional characters from the core stream that are not * returned, but will be retained for subsequent read operations. */ int bsreadlna (bstring r, struct bStream * s, char terminator) { @@ -2038,9 +2038,9 @@ struct tagbstring x; /* int bsreadlnsa (bstring r, struct bStream * s, bstring term) * - * Read a bstring terminated by any character in the term string or the end - * of the stream from the bStream (s) and return it into the parameter r. - * This function may read additional characters from the core stream that + * Read a bstring terminated by any character in the term string or the end + * of the stream from the bStream (s) and return it into the parameter r. + * This function may read additional characters from the core stream that * are not returned, but will be retained for subsequent read operations. */ int bsreadlnsa (bstring r, struct bStream * s, const_bstring term) { @@ -2108,9 +2108,9 @@ struct charField cf; /* int bsreada (bstring r, struct bStream * s, int n) * - * Read a bstring of length n (or, if it is fewer, as many bytes as is - * remaining) from the bStream. This function may read additional - * characters from the core stream that are not returned, but will be + * Read a bstring of length n (or, if it is fewer, as many bytes as is + * remaining) from the bStream. This function may read additional + * characters from the core stream that are not returned, but will be * retained for subsequent read operations. This function will not read * additional characters from the core stream beyond virtual stream pointer. */ @@ -2174,8 +2174,8 @@ struct tagbstring x; /* int bsreadln (bstring r, struct bStream * s, char terminator) * * Read a bstring terminated by the terminator character or the end of the - * stream from the bStream (s) and return it into the parameter r. This - * function may read additional characters from the core stream that are not + * stream from the bStream (s) and return it into the parameter r. This + * function may read additional characters from the core stream that are not * returned, but will be retained for subsequent read operations. */ int bsreadln (bstring r, struct bStream * s, char terminator) { @@ -2188,13 +2188,13 @@ int bsreadln (bstring r, struct bStream * s, char terminator) { /* int bsreadlns (bstring r, struct bStream * s, bstring term) * - * Read a bstring terminated by any character in the term string or the end - * of the stream from the bStream (s) and return it into the parameter r. - * This function may read additional characters from the core stream that + * Read a bstring terminated by any character in the term string or the end + * of the stream from the bStream (s) and return it into the parameter r. + * This function may read additional characters from the core stream that * are not returned, but will be retained for subsequent read operations. */ int bsreadlns (bstring r, struct bStream * s, const_bstring term) { - if (s == NULL || s->buff == NULL || r == NULL || term == NULL + if (s == NULL || s->buff == NULL || r == NULL || term == NULL || term->data == NULL || r->mlen <= 0) return BSTR_ERR; if (term->slen == 1) return bsreadln (r, s, term->data[0]); if (term->slen < 1) return BSTR_ERR; @@ -2205,9 +2205,9 @@ int bsreadlns (bstring r, struct bStream * s, const_bstring term) { /* int bsread (bstring r, struct bStream * s, int n) * - * Read a bstring of length n (or, if it is fewer, as many bytes as is - * remaining) from the bStream. This function may read additional - * characters from the core stream that are not returned, but will be + * Read a bstring of length n (or, if it is fewer, as many bytes as is + * remaining) from the bStream. This function may read additional + * characters from the core stream that are not returned, but will be * retained for subsequent read operations. This function will not read * additional characters from the core stream beyond virtual stream pointer. */ @@ -2221,8 +2221,8 @@ int bsread (bstring r, struct bStream * s, int n) { /* int bsunread (struct bStream * s, const_bstring b) * - * Insert a bstring into the bStream at the current position. These - * characters will be read prior to those that actually come from the core + * Insert a bstring into the bStream at the current position. These + * characters will be read prior to those that actually come from the core * stream. */ int bsunread (struct bStream * s, const_bstring b) { @@ -2232,7 +2232,7 @@ int bsunread (struct bStream * s, const_bstring b) { /* int bspeek (bstring r, const struct bStream * s) * - * Return the currently buffered characters from the bStream that will be + * Return the currently buffered characters from the bStream that will be * read prior to reads from the core stream. */ int bspeek (bstring r, const struct bStream * s) { @@ -2242,8 +2242,8 @@ int bspeek (bstring r, const struct bStream * s) { /* bstring bjoin (const struct bstrList * bl, const_bstring sep); * - * Join the entries of a bstrList into one bstring by sequentially - * concatenating them with the sep string in between. If there is an error + * Join the entries of a bstrList into one bstring by sequentially + * concatenating them with the sep string in between. If there is an error * NULL is returned, otherwise a bstring with the correct result is returned. */ bstring bjoin (const struct bstrList * bl, const_bstring sep) { @@ -2288,37 +2288,37 @@ int i, c, v; #define BSSSC_BUFF_LEN (256) -/* int bssplitscb (struct bStream * s, const_bstring splitStr, +/* int bssplitscb (struct bStream * s, const_bstring splitStr, * int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) * - * Iterate the set of disjoint sequential substrings read from a stream - * divided by any of the characters in splitStr. An empty splitStr causes + * Iterate the set of disjoint sequential substrings read from a stream + * divided by any of the characters in splitStr. An empty splitStr causes * the whole stream to be iterated once. * - * Note: At the point of calling the cb function, the bStream pointer is - * pointed exactly at the position right after having read the split + * Note: At the point of calling the cb function, the bStream pointer is + * pointed exactly at the position right after having read the split * character. The cb function can act on the stream by causing the bStream * pointer to move, and bssplitscb will continue by starting the next split * at the position of the pointer after the return from cb. * * However, if the cb causes the bStream s to be destroyed then the cb must - * return with a negative value, otherwise bssplitscb will continue in an + * return with a negative value, otherwise bssplitscb will continue in an * undefined manner. */ -int bssplitscb (struct bStream * s, const_bstring splitStr, +int bssplitscb (struct bStream * s, const_bstring splitStr, int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) { struct charField chrs; bstring buff; int i, p, ret; - if (cb == NULL || s == NULL || s->readFnPtr == NULL + if (cb == NULL || s == NULL || s->readFnPtr == NULL || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; if (NULL == (buff = bfromcstr (""))) return BSTR_ERR; if (splitStr->slen == 0) { while (bsreada (buff, s, BSSSC_BUFF_LEN) >= 0) ; - if ((ret = cb (parm, 0, buff)) > 0) + if ((ret = cb (parm, 0, buff)) > 0) ret = 0; } else { buildCharField (&chrs, splitStr); @@ -2354,29 +2354,29 @@ int i, p, ret; return ret; } -/* int bssplitstrcb (struct bStream * s, const_bstring splitStr, +/* int bssplitstrcb (struct bStream * s, const_bstring splitStr, * int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) * - * Iterate the set of disjoint sequential substrings read from a stream - * divided by the entire substring splitStr. An empty splitStr causes + * Iterate the set of disjoint sequential substrings read from a stream + * divided by the entire substring splitStr. An empty splitStr causes * each character of the stream to be iterated. * - * Note: At the point of calling the cb function, the bStream pointer is - * pointed exactly at the position right after having read the split + * Note: At the point of calling the cb function, the bStream pointer is + * pointed exactly at the position right after having read the split * character. The cb function can act on the stream by causing the bStream * pointer to move, and bssplitscb will continue by starting the next split * at the position of the pointer after the return from cb. * * However, if the cb causes the bStream s to be destroyed then the cb must - * return with a negative value, otherwise bssplitscb will continue in an + * return with a negative value, otherwise bssplitscb will continue in an * undefined manner. */ -int bssplitstrcb (struct bStream * s, const_bstring splitStr, +int bssplitstrcb (struct bStream * s, const_bstring splitStr, int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) { bstring buff; int i, p, ret; - if (cb == NULL || s == NULL || s->readFnPtr == NULL + if (cb == NULL || s == NULL || s->readFnPtr == NULL || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; if (splitStr->slen == 1) return bssplitscb (s, splitStr, cb, parm); @@ -2508,20 +2508,20 @@ size_t nsz; * Iterate the set of disjoint sequential substrings over str divided by the * character in splitChar. * - * Note: Non-destructive modification of str from within the cb function - * while performing this split is not undefined. bsplitcb behaves in - * sequential lock step with calls to cb. I.e., after returning from a cb - * that return a non-negative integer, bsplitcb continues from the position - * 1 character after the last detected split character and it will halt - * immediately if the length of str falls below this point. However, if the - * cb function destroys str, then it *must* return with a negative value, + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. bsplitcb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, bsplitcb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, * otherwise bsplitcb will continue in an undefined manner. */ int bsplitcb (const_bstring str, unsigned char splitChar, int pos, int (* cb) (void * parm, int ofs, int len), void * parm) { int i, p, ret; - if (cb == NULL || str == NULL || pos < 0 || pos > str->slen) + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen) return BSTR_ERR; p = pos; @@ -2538,17 +2538,17 @@ int i, p, ret; /* int bsplitscb (const_bstring str, const_bstring splitStr, int pos, * int (* cb) (void * parm, int ofs, int len), void * parm) * - * Iterate the set of disjoint sequential substrings over str divided by any + * Iterate the set of disjoint sequential substrings over str divided by any * of the characters in splitStr. An empty splitStr causes the whole str to * be iterated once. * - * Note: Non-destructive modification of str from within the cb function - * while performing this split is not undefined. bsplitscb behaves in - * sequential lock step with calls to cb. I.e., after returning from a cb - * that return a non-negative integer, bsplitscb continues from the position - * 1 character after the last detected split character and it will halt - * immediately if the length of str falls below this point. However, if the - * cb function destroys str, then it *must* return with a negative value, + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. bsplitscb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, bsplitscb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, * otherwise bsplitscb will continue in an undefined manner. */ int bsplitscb (const_bstring str, const_bstring splitStr, int pos, @@ -2556,14 +2556,14 @@ int bsplitscb (const_bstring str, const_bstring splitStr, int pos, struct charField chrs; int i, p, ret; - if (cb == NULL || str == NULL || pos < 0 || pos > str->slen + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; if (splitStr->slen == 0) { if ((ret = cb (parm, 0, str->slen)) > 0) ret = 0; return ret; } - if (splitStr->slen == 1) + if (splitStr->slen == 1) return bsplitcb (str, splitStr->data[0], pos, cb, parm); buildCharField (&chrs, splitStr); @@ -2582,24 +2582,24 @@ int i, p, ret; /* int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, * int (* cb) (void * parm, int ofs, int len), void * parm) * - * Iterate the set of disjoint sequential substrings over str divided by the - * substring splitStr. An empty splitStr causes the whole str to be + * Iterate the set of disjoint sequential substrings over str divided by the + * substring splitStr. An empty splitStr causes the whole str to be * iterated once. * - * Note: Non-destructive modification of str from within the cb function - * while performing this split is not undefined. bsplitstrcb behaves in - * sequential lock step with calls to cb. I.e., after returning from a cb - * that return a non-negative integer, bsplitscb continues from the position - * 1 character after the last detected split character and it will halt - * immediately if the length of str falls below this point. However, if the - * cb function destroys str, then it *must* return with a negative value, + * Note: Non-destructive modification of str from within the cb function + * while performing this split is not undefined. bsplitstrcb behaves in + * sequential lock step with calls to cb. I.e., after returning from a cb + * that return a non-negative integer, bsplitscb continues from the position + * 1 character after the last detected split character and it will halt + * immediately if the length of str falls below this point. However, if the + * cb function destroys str, then it *must* return with a negative value, * otherwise bsplitscb will continue in an undefined manner. */ int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, int (* cb) (void * parm, int ofs, int len), void * parm) { int i, p, ret; - if (cb == NULL || str == NULL || pos < 0 || pos > str->slen + if (cb == NULL || str == NULL || pos < 0 || pos > str->slen || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR; if (0 == splitStr->slen) { @@ -2609,7 +2609,7 @@ int i, p, ret; return BSTR_OK; } - if (splitStr->slen == 1) + if (splitStr->slen == 1) return bsplitcb (str, splitStr->data[0], pos, cb, parm); for (i=p=pos; i <= str->slen - splitStr->slen; i++) { @@ -2654,7 +2654,7 @@ struct genBstrList * g = (struct genBstrList *) parm; /* struct bstrList * bsplit (const_bstring str, unsigned char splitChar) * * Create an array of sequential substrings from str divided by the character - * splitChar. + * splitChar. */ struct bstrList * bsplit (const_bstring str, unsigned char splitChar) { struct genBstrList g; @@ -2709,7 +2709,7 @@ struct genBstrList g; /* struct bstrList * bsplits (const_bstring str, bstring splitStr) * - * Create an array of sequential substrings from str divided by any of the + * Create an array of sequential substrings from str divided by any of the * characters in splitStr. An empty splitStr causes a single entry bstrList * containing a copy of str to be returned. */ @@ -2749,14 +2749,14 @@ struct genBstrList g; #define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);} #else #ifdef BSTRLIB_NOVSNP -/* This is just a hack. If you are using a system without a vsnprintf, it is +/* This is just a hack. If you are using a system without a vsnprintf, it is not recommended that bformat be used at all. */ #define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} #define START_VSNBUFF (256) #else #if defined(__GNUC__) && !defined(__APPLE__) -/* Something is making gcc complain about this prototype not being here, so +/* Something is making gcc complain about this prototype not being here, so I've just gone ahead and put it in. */ extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); #endif @@ -2771,19 +2771,19 @@ extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); #define START_VSNBUFF (16) #endif -/* On IRIX vsnprintf returns n-1 when the operation would overflow the target - buffer, WATCOM and MSVC both return -1, while C99 requires that the +/* On IRIX vsnprintf returns n-1 when the operation would overflow the target + buffer, WATCOM and MSVC both return -1, while C99 requires that the returned value be exactly what the length would be if the buffer would be - large enough. This leads to the idea that if the return value is larger + large enough. This leads to the idea that if the return value is larger than n, then changing n to the return value will reduce the number of iterations required. */ /* int bformata (bstring b, const char * fmt, ...) * - * After the first parameter, it takes the same parameters as printf (), but - * rather than outputting results to stdio, it appends the results to - * a bstring which contains what would have been output. Note that if there - * is an early generation of a '\0' character, the bstring will be truncated + * After the first parameter, it takes the same parameters as printf (), but + * rather than outputting results to stdio, it appends the results to + * a bstring which contains what would have been output. Note that if there + * is an early generation of a '\0' character, the bstring will be truncated * to this end point. */ int bformata (bstring b, const char * fmt, ...) { @@ -2791,7 +2791,7 @@ va_list arglist; bstring buff; int n, r; - if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 + if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR; /* Since the length is not determinable beforehand, a search is @@ -2829,9 +2829,9 @@ int n, r; /* int bassignformat (bstring b, const char * fmt, ...) * - * After the first parameter, it takes the same parameters as printf (), but - * rather than outputting results to stdio, it outputs the results to - * the bstring parameter b. Note that if there is an early generation of a + * After the first parameter, it takes the same parameters as printf (), but + * rather than outputting results to stdio, it outputs the results to + * the bstring parameter b. Note that if there is an early generation of a * '\0' character, the bstring will be truncated to this end point. */ int bassignformat (bstring b, const char * fmt, ...) { @@ -2839,7 +2839,7 @@ va_list arglist; bstring buff; int n, r; - if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 + if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR; /* Since the length is not determinable beforehand, a search is @@ -2879,7 +2879,7 @@ int n, r; * * Takes the same parameters as printf (), but rather than outputting results * to stdio, it forms a bstring which contains what would have been output. - * Note that if there is an early generation of a '\0' character, the + * Note that if there is an early generation of a '\0' character, the * bstring will be truncated to this end point. */ bstring bformat (const char * fmt, ...) { @@ -2922,22 +2922,22 @@ int n, r; /* int bvcformata (bstring b, int count, const char * fmt, va_list arglist) * - * The bvcformata function formats data under control of the format control - * string fmt and attempts to append the result to b. The fmt parameter is - * the same as that of the printf function. The variable argument list is + * The bvcformata function formats data under control of the format control + * string fmt and attempts to append the result to b. The fmt parameter is + * the same as that of the printf function. The variable argument list is * replaced with arglist, which has been initialized by the va_start macro. * The size of the output is upper bounded by count. If the required output * exceeds count, the string b is not augmented with any contents and a value * below BSTR_ERR is returned. If a value below -count is returned then it * is recommended that the negative of this value be used as an update to the - * count in a subsequent pass. On other errors, such as running out of - * memory, parameter errors or numeric wrap around BSTR_ERR is returned. - * BSTR_OK is returned when the output is successfully generated and + * count in a subsequent pass. On other errors, such as running out of + * memory, parameter errors or numeric wrap around BSTR_ERR is returned. + * BSTR_OK is returned when the output is successfully generated and * appended to b. * * Note: There is no sanity checking of arglist, and this function is - * destructive of the contents of b from the b->slen point onward. If there - * is an early generation of a '\0' character, the bstring will be truncated + * destructive of the contents of b from the b->slen point onward. If there + * is an early generation of a '\0' character, the bstring will be truncated * to this end point. */ int bvcformata (bstring b, int count, const char * fmt, va_list arg) { @@ -2958,7 +2958,7 @@ int n, r, l; return BSTR_OK; } - /* Abort, since the buffer was not large enough. The return value + /* Abort, since the buffer was not large enough. The return value tries to help set what the retry length should be. */ b->data[b->slen] = '\0'; diff --git a/security.txt b/security.txt index 9761409..38c852c 100644 --- a/security.txt +++ b/security.txt @@ -8,35 +8,35 @@ by Paul Hsieh Introduction ------------ -The Better String library (hereafter referred to as Bstrlib) is an attempt to -provide improved string processing functionality to the C and C++ languages. -At the heart of the Bstrlib is the management of "bstring"s which are a -significant improvement over '\0' terminated char buffers. See the +The Better String library (hereafter referred to as Bstrlib) is an attempt to +provide improved string processing functionality to the C and C++ languages. +At the heart of the Bstrlib is the management of "bstring"s which are a +significant improvement over '\0' terminated char buffers. See the accompanying documenation file bstrlib.txt for more information. -DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT -NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Like any software, there is always a possibility of failure due to a flawed -implementation. Nevertheless a good faith effort has been made to minimize -such flaws in Bstrlib. Also, use of Bstrlib by itself will not make an +implementation. Nevertheless a good faith effort has been made to minimize +such flaws in Bstrlib. Also, use of Bstrlib by itself will not make an application secure or free from implementation failures. However, it is the -author's conviction that use of Bstrlib can greatly facilitate the creation +author's conviction that use of Bstrlib can greatly facilitate the creation of software meeting the highest possible standards of security. -Part of the reason why this document has been created, is for the purpose of -security auditing, or the creation of further "Statements on Security" for -software that is created that uses Bstrlib. An auditor may check the claims -below against Bstrlib, and use this as a basis for analysis of software which +Part of the reason why this document has been created, is for the purpose of +security auditing, or the creation of further "Statements on Security" for +software that is created that uses Bstrlib. An auditor may check the claims +below against Bstrlib, and use this as a basis for analysis of software which uses Bstrlib. =============================================================================== @@ -45,15 +45,15 @@ Statement on Security --------------------- This is a document intended to give consumers of the Better String Library -who are interested in security an idea of where the Better String Library -stands on various security issues. Any deviation observed in the actual -library itself from the descriptions below should be considered an +who are interested in security an idea of where the Better String Library +stands on various security issues. Any deviation observed in the actual +library itself from the descriptions below should be considered an implementation error, not a design flaw. This statement is not an analytical proof of correctness or an outline of one but rather an assertion similar to a scientific claim or hypothesis. By use, -testing and open independent examination (otherwise known as scientific -falsifiability), the credibility of the claims made below can rise to the +testing and open independent examination (otherwise known as scientific +falsifiability), the credibility of the claims made below can rise to the level of an established theory. Common security issues: @@ -61,29 +61,30 @@ Common security issues: 1. Buffer Overflows -The Bstrlib API allows the programmer a way to deal with strings without -having to deal with the buffers containing them. Ordinary usage of the +The Bstrlib API allows the programmer a way to deal with strings without +having to deal with the buffers containing them. Ordinary usage of the Bstrlib API itself makes buffer overflows impossible. -Furthermore, the Bstrlib API has a superset of basic string functionality as -compared to the C library's char * functions, C++'s std::string class and -Microsoft's MFC based CString class. It also has abstracted mechanisms for -dealing with IO. This is important as it gives developers a way of migrating +Furthermore, the Bstrlib API has a superset of basic string functionality as +compared to the C library's char * functions, C++'s std::string class and +Microsoft's MFC based CString class. It also has abstracted mechanisms for +dealing with IO. This is important as it gives developers a way of migrating all their code from a functionality point of view. 2. Memory size overflow/wrap around attack -Bstrlib is, by design, impervious to memory size overflow attacks. The -reason is it is resiliant to length overflows is that bstring lengths are -bounded above by INT_MAX, instead of ~(size_t)0. So length addition -overflows cause a wrap around of the integer value making them negative -causing balloc() to fail before an erroneous operation can occurr. Attempted -conversions of char * strings which may have lengths greater than INT_MAX are -detected and the conversion is aborted. +By design, Bstrlib is impervious to memory size overflow attacks. The +reason is that it detects length overflows and leads to a result error before +the operation attempts to proceed. Attempted conversions of char* strings +which may have lengths greater than INT_MAX are detected and the conversion +is aborted. If the memory to hold the string exceeds the available memory +for it, again, the result is aborted without changing the prior state of the +strings. -It is unknown if this property holds on machines that don't represent -integers as 2s complement. It is recommended that Bstrlib be carefully -auditted by anyone using a system which is not 2s complement based. +These behaviors rely on the use of 2s complement by the underlying machine +architecture. It is unknown if these properties hold on machines that do +not represent integers as 2s complement. It is recommended that Bstrlib be +carefully auditted by anyone using a system which is not 2s complement based. 3. Constant string protection @@ -93,7 +94,7 @@ be modified or deallocated directly through the Bstrlib API, and this cannot be subverted by casting or other type coercion. This is independent of the use of the const_bstring data type. -The Bstrlib C API uses the type const_bstring to specify bstring parameters +The Bstrlib C API uses the type const_bstring to specify bstring parameters whose contents do not change. Although the C language cannot enforce this, this is nevertheless guaranteed by the implementation of the Bstrlib library of C functions. The C++ API enforces the const attribute on CBString types @@ -101,59 +102,59 @@ correctly. 4. Aliased bstring support -Bstrlib detects and supports aliased parameter management throughout the API. +Bstrlib detects and supports aliased parameter management throughout the API. The kind of aliasing that is allowed is the one where pointers of the same -basic type may be pointing to overlapping objects (this is the assumption the -ANSI C99 specification makes.) Each function behaves as if all read-only -parameters were copied to temporaries which are used in their stead before -the function is enacted (it rarely actually does this). No function in the -Bstrlib uses the "restrict" parameter attribute from the ANSI C99 +basic type may be pointing to overlapping objects (this is the assumption the +ANSI C99 specification makes.) Each function behaves as if all read-only +parameters were copied to temporaries which are used in their stead before +the function is enacted (it rarely actually does this). No function in the +Bstrlib uses the "restrict" parameter attribute from the ANSI C99 specification. 5. Information leaking -In bstraux.h, using the semantically equivalent macros bSecureDestroy() and -bSecureWriteProtect() in place of bdestroy() and bwriteprotect() respectively -will ensure that stale data does not linger in the heap's free space after +In bstraux.h, using the semantically equivalent macros bSecureDestroy() and +bSecureWriteProtect() in place of bdestroy() and bwriteprotect() respectively +will ensure that stale data does not linger in the heap's free space after strings have been released back to memory. Created bstrings or CBStrings -are not linked to anything external to themselves, and thus cannot expose +are not linked to anything external to themselves, and thus cannot expose deterministic data leaking. If a bstring is resized, the preimage may exist -as a copy that is released to the heap. Thus for sensitive data, the bstring -should be sufficiently presized before manipulated so that it is not resized. -bSecureInput() has been supplied in bstraux.c, which can be used to obtain -input securely without any risk of leaving any part of the input image in the +as a copy that is released to the heap. Thus for sensitive data, the bstring +should be sufficiently presized before manipulated so that it is not resized. +bSecureInput() has been supplied in bstraux.c, which can be used to obtain +input securely without any risk of leaving any part of the input image in the heap except for the allocated bstring that is returned. 6. Memory leaking -Bstrlib can be built using memdbg.h enabled via the BSTRLIB_MEMORY_DEBUG +Bstrlib can be built using memdbg.h enabled via the BSTRLIB_MEMORY_DEBUG macro. User generated definitions for malloc, realloc and free can then be -supplied which can implement special strategies for memory corruption -detection or memory leaking. Otherwise, bstrlib does not do anything out of -the ordinary to attempt to deal with the standard problem of memory leaking -(i.e., losing references to allocated memory) when programming in the C and -C++ languages. However, it does not compound the problem any more than exists -either, as it doesn't have any intrinsic inescapable leaks in it. Bstrlib -does not preclude the use of automatic garbage collection mechanisms such as +supplied which can implement special strategies for memory corruption +detection or memory leaking. Otherwise, bstrlib does not do anything out of +the ordinary to attempt to deal with the standard problem of memory leaking +(i.e., losing references to allocated memory) when programming in the C and +C++ languages. However, it does not compound the problem any more than exists +either, as it doesn't have any intrinsic inescapable leaks in it. Bstrlib +does not preclude the use of automatic garbage collection mechanisms such as the Boehm garbage collector. 7. Encryption -Bstrlib does not present any built-in encryption mechanism. However, it -supports full binary contents in its data buffers, so any standard block -based encryption mechanism can make direct use of bstrings/CBStrings for +Bstrlib does not present any built-in encryption mechanism. However, it +supports full binary contents in its data buffers, so any standard block +based encryption mechanism can make direct use of bstrings/CBStrings for buffer management. 8. Double freeing -Freeing a pointer that is already free is an extremely rare, but nevertheless +Freeing a pointer that is already free is an extremely rare, but nevertheless a potentially ruthlessly corrupting operation (its possible to cause Win 98 to reboot, by calling free mulitiple times on already freed data using the WATCOM CRT.) Bstrlib invalidates the bstring header data before freeing, so that in -many cases a double free will be detected and an error will be reported +many cases a double free will be detected and an error will be reported (though this behaviour is not guaranteed and should not be relied on). -Using bstrFree pervasively (instead of bdestroy) can lead to somewhat +Using bstrFree pervasively (instead of bdestroy) can lead to somewhat improved invalid free avoidance (it is completely safe whenever bstring instances are only stored in unique variables). For example: @@ -173,21 +174,21 @@ instances are only stored in unique variables). For example: 9. Resource based denial of service bSecureInput() has been supplied in bstraux.c. It has an optional upper limit -for input length. But unlike fgets(), it is also easily determined if the -buffer has been truncated early. In this way, a program can set an upper limit -on input sizes while still allowing for implementing context specific -truncation semantics (i.e., does the program consume but dump the extra +for input length. But unlike fgets(), it is also easily determined if the +buffer has been truncated early. In this way, a program can set an upper +limit on input sizes while still allowing for implementing context specific +truncation semantics (i.e., does the program consume but dump the extra input, or does it consume it in later inputs?) 10. Mixing char *'s and bstrings The bstring and char * representations are not identical. So there is a risk when converting back and forth that data may lost. Essentially bstrings can -contain '\0' as a valid non-terminating character, while char * strings -cannot and in fact must use the character as a terminator. The risk of data +contain '\0' as a valid non-terminating character, while char * strings +cannot and in fact must use the character as a terminator. The risk of data loss is very low, since: - A) the simple method of only using bstrings in a char * semantically + A) the simple method of only using bstrings in a char * semantically compatible way is both easy to achieve and pervasively supported. B) obtaining '\0' content in a string is either deliberate or indicative of another, likely more serious problem in the code. @@ -199,10 +200,10 @@ Marginal security issues: 11. 8-bit versus 9-bit portability -Bstrlib uses CHAR_BIT and other limits.h constants to the maximum extent -possible to avoid portability problems. However, Bstrlib has not been tested -on any system that does not represent char as 8-bits. So whether or not it -works on 9-bit systems is an open question. It is recommended that Bstrlib be +Bstrlib uses CHAR_BIT and other limits.h constants to the maximum extent +possible to avoid portability problems. However, Bstrlib has not been tested +on any system that does not represent char as 8-bits. So whether or not it +works on 9-bit systems is an open question. It is recommended that Bstrlib be carefully auditted by anyone using a system in which CHAR_BIT is not 8. 12. EBCDIC/ASCII/UTF-8 data representation attacks. @@ -216,6 +217,6 @@ Obscure issues: 13. Data attributes -There is no support for a Perl-like "taint" attribute, however, an example of +There is no support for a Perl-like "taint" attribute, however, an example of how to do this using C++'s type system is given as an example.