summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-06-28 00:50:10 +0000
committerBenny Prijono <bennylp@teluu.com>2007-06-28 00:50:10 +0000
commitfbdd259dcedfaf197e35922d8018171a5d94b656 (patch)
tree3e588737d23bc5775cf342b0c743302cba08f964
parentdc88226fa06a68d43dfcd716fc50635c0eddf535 (diff)
Fixed ticket #348: various bugs in string comparison functions
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1397 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/include/pj/string.h8
-rw-r--r--pjlib/include/pj/string_i.h157
-rw-r--r--pjlib/src/pjlib-test/string.c124
3 files changed, 160 insertions, 129 deletions
diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h
index 26e7fa6c..8124539f 100644
--- a/pjlib/include/pj/string.h
+++ b/pjlib/include/pj/string.h
@@ -341,7 +341,7 @@ PJ_IDECL(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
pj_size_t len);
/**
- * Perform lowercase comparison to the strings.
+ * Perform case-insensitive comparison to the strings.
*
* @param str1 The string to compare.
* @param str2 The string to compare.
@@ -398,7 +398,7 @@ PJ_IDECL(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2);
#endif
/**
- * Perform lowercase comparison to the strings.
+ * Perform case-insensitive comparison to the strings.
*
* @param str1 The string to compare.
* @param str2 The string to compare.
@@ -411,7 +411,7 @@ PJ_IDECL(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2);
PJ_IDECL(int) pj_stricmp2( const pj_str_t *str1, const char *str2);
/**
- * Perform lowercase comparison to the strings.
+ * Perform case-insensitive comparison to the strings.
*
* @param str1 The string to compare.
* @param str2 The string to compare.
@@ -426,7 +426,7 @@ PJ_IDECL(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
pj_size_t len);
/**
- * Perform lowercase comparison to the strings.
+ * Perform case-insensitive comparison to the strings.
*
* @param str1 The string to compare.
* @param str2 The string to compare.
diff --git a/pjlib/include/pj/string_i.h b/pjlib/include/pj/string_i.h
index 7430b626..1590b049 100644
--- a/pjlib/include/pj/string_i.h
+++ b/pjlib/include/pj/string_i.h
@@ -135,63 +135,86 @@ PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,
PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
{
- pj_ssize_t diff;
-
- diff = str1->slen - str2->slen;
- if (diff) {
- return diff > 0 ? 1 : -1;
- } else if (str1->ptr && str1->slen) {
- return memcmp(str1->ptr, str2->ptr, str1->slen);
+ if (str1->slen == 0) {
+ return str2->slen==0 ? 0 : -1;
+ } else if (str2->slen == 0) {
+ return 1;
} else {
- return 0;
+ int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
+ int res = pj_memcmp(str1->ptr, str2->ptr, min);
+ if (res == 0) {
+ return (str1->slen < str2->slen) ? -1 :
+ (str1->slen == str2->slen ? 0 : 1);
+ } else {
+ return res;
+ }
}
}
PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2,
pj_size_t len)
{
- if (str1->ptr && str2->ptr)
- return memcmp(str1->ptr, str2->ptr, len);
- else if (str2->ptr)
- return str2->slen==0 ? 0 : -1;
- else if (str1->ptr)
- return str1->slen==0 ? 0 : 1;
- else
- return 0;
+ pj_str_t copy1, copy2;
+
+ if (len < (unsigned)str1->slen) {
+ copy1.ptr = str1->ptr;
+ copy1.slen = len;
+ str1 = &copy1;
+ }
+
+ if (len < (unsigned)str2->slen) {
+ copy2.ptr = str2->ptr;
+ copy2.slen = len;
+ str2 = &copy2;
+ }
+
+ return pj_strcmp(str1, str2);
}
PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
pj_size_t len)
{
- if (len == 0)
- return 0;
- else if (str1->ptr && str2)
- return memcmp(str1->ptr, str2, len);
- else if (str1->ptr)
- return str1->slen==0 ? 0 : 1;
- else if (str2)
- return *str2=='\0' ? 0 : -1;
- else
- return 0;
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.slen = 0;
+ }
+
+ return pj_strncmp(str1, &copy2, len);
}
PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
{
- if (str1->slen == 0) {
- return (!str2 || *str2=='\0') ? 0 : -1;
- } else
- return pj_strncmp2( str1, str2, str1->slen);
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.slen = 0;
+ }
+
+ return pj_strcmp(str1, &copy2);
}
PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
{
- register int len = str1->slen;
- if (len != str2->slen) {
- return (int)(len - str2->slen);
- } else if (len == 0) {
- return 0;
+ if (str1->slen == 0) {
+ return str2->slen==0 ? 0 : -1;
+ } else if (str2->slen == 0) {
+ return 1;
} else {
- return pj_ansi_strnicmp(str1->ptr, str2->ptr, len);
+ int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
+ int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);
+ if (res == 0) {
+ return (str1->slen < str2->slen) ? -1 :
+ (str1->slen == str2->slen ? 0 : 1);
+ } else {
+ return res;
+ }
}
}
@@ -268,43 +291,51 @@ PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
{
- if (str1->ptr && str2)
- return pj_ansi_strnicmp(str1->ptr, str2, str1->slen);
- else if (str2)
- return (*str2=='\0') ? 0 : -1;
- else if (str1->ptr)
- return (str1->slen==0) ? 0 : 1;
- else
- return 0;
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.slen = 0;
+ }
+
+ return pj_stricmp(str1, &copy2);
}
PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
pj_size_t len)
{
- if (str1->ptr && str2->ptr)
- return pj_ansi_strnicmp(str1->ptr, str2->ptr, len);
- else if (str2->ptr)
- return str2->slen==0 ? 0 : -1;
- else if (str1->ptr)
- return str1->slen==0 ? 0 : 1;
- else
- return 0;
+ pj_str_t copy1, copy2;
+
+ if (len < (unsigned)str1->slen) {
+ copy1.ptr = str1->ptr;
+ copy1.slen = len;
+ str1 = &copy1;
+ }
+
+ if (len < (unsigned)str2->slen) {
+ copy2.ptr = str2->ptr;
+ copy2.slen = len;
+ str2 = &copy2;
+ }
+
+ return pj_stricmp(str1, str2);
}
PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2,
pj_size_t len)
{
- if (len == 0)
- return 0;
- else if (str1->ptr && str2)
- return pj_ansi_strnicmp(str1->ptr, str2, len);
- else if (str1->ptr)
- return str1->slen==0 ? 0 : 1;
- else if (str2)
- return *str2=='\0' ? 0 : -1;
- else
- return 0;
+ pj_str_t copy2;
+
+ if (str2) {
+ copy2.ptr = (char*)str2;
+ copy2.slen = pj_ansi_strlen(str2);
+ } else {
+ copy2.slen = 0;
+ }
+ return pj_strnicmp(str1, &copy2, len);
}
PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
@@ -317,7 +348,7 @@ PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)
{
- unsigned len = pj_ansi_strlen(str);
+ unsigned len = str? pj_ansi_strlen(str) : 0;
if (len) {
pj_memcpy(dst->ptr + dst->slen, str, len);
dst->slen += len;
diff --git a/pjlib/src/pjlib-test/string.c b/pjlib/src/pjlib-test/string.c
index dc845d07..a436c9ee 100644
--- a/pjlib/src/pjlib-test/string.c
+++ b/pjlib/src/pjlib-test/string.c
@@ -71,11 +71,11 @@
/* See if both integers have the same sign */
PJ_INLINE(int) cmp(const char *expr, int i, int j)
{
- i = !((i>0 && j>0) || (i<0 && j<0) || (i==0 && j==0));
- if (i) {
+ int r = !((i>0 && j>0) || (i<0 && j<0) || (i==0 && j==0));
+ if (r) {
PJ_LOG(3,(THIS_FILE," error: %s: expecting %d, got %d", expr, j, i));
}
- return i;
+ return r;
}
#else
/* For strict comparison, must be equal */
@@ -94,7 +94,7 @@ static int stricmp_test(void)
* In addition, it also tests pj_stricmp2(), pj_strnicmp(), and
* pj_strnicmp2().
*/
-#define STRTEST(res,S1,S2,code) \
+#define STRTEST(res,res2,S1,S2,code) \
do { \
s1.ptr=S1; s1.slen=(S1)?len:0; \
s2.ptr=S2; s2.slen=(S2)?len:0; \
@@ -108,7 +108,7 @@ static int stricmp_test(void)
pj_get_timestamp(&t2); \
pj_sub_timestamp(&t2, &t1); \
pj_add_timestamp(&e2, &t2); \
- if (C(pj_stricmp2(&s1,S2),res)) return code*10; \
+ if (C(pj_stricmp2(&s1,S2),res2)) return code*10; \
if (C(pj_strnicmp(&s1,&s2,len),res)) return code*100; \
if (C(pj_strnicmp2(&s1,S2,len),res)) return code*1000; \
} while (0)
@@ -127,107 +127,107 @@ static int stricmp_test(void)
/* Compare empty strings. */
len=0;
- STRTEST( 0, "","",-500);
- STRTEST( 0, SNULL,"",-502);
- STRTEST( 0, "",SNULL,-504);
- STRTEST( 0, SNULL,SNULL,-506);
- STRTEST( 0, "hello","world",-508);
+ STRTEST( 0, 0, "","",-500);
+ STRTEST( 0, 0, SNULL,"",-502);
+ STRTEST( 0, 0, "",SNULL,-504);
+ STRTEST( 0, 0, SNULL,SNULL,-506);
+ STRTEST( 0, -1, "hello","world",-508);
/* equal, length=1
* use buffer to simulate non-aligned string.
*/
buf = "a""A";
len=1;
- STRTEST( 0, "a",buf+0,-510);
- STRTEST( 0, "a",buf+1,-512);
- STRTEST( -1, "O", "P", -514);
- STRTEST(-1, SNULL, "a", -516);
- STRTEST(1, "a", SNULL, -518);
+ STRTEST( 0, -1, "a",buf+0,-510);
+ STRTEST( 0, 0, "a",buf+1,-512);
+ STRTEST(-1, -1, "O", "P", -514);
+ STRTEST(-1, -1, SNULL, "a", -516);
+ STRTEST( 1, 1, "a", SNULL, -518);
/* equal, length=2
* use buffer to simulate non-aligned string.
*/
buf = "aa""Aa""aA""AA";
len=2;
- STRTEST( 0, "aa",buf+0,-520);
- STRTEST( 0, "aa",buf+2,-522);
- STRTEST( 0, "aa",buf+4,-524);
- STRTEST( 0, "aa",buf+6,-524);
+ STRTEST( 0, -1, "aa",buf+0,-520);
+ STRTEST( 0, -1, "aa",buf+2,-522);
+ STRTEST( 0, -1, "aa",buf+4,-524);
+ STRTEST( 0, 0, "aa",buf+6,-524);
/* equal, length=3
* use buffer to simulate non-aligned string.
*/
buf = "aaa""Aaa""aAa""aaA""AAa""aAA""AaA""AAA";
len=3;
- STRTEST( 0, "aaa",buf+0,-530);
- STRTEST( 0, "aaa",buf+3,-532);
- STRTEST( 0, "aaa",buf+6,-534);
- STRTEST( 0, "aaa",buf+9,-536);
- STRTEST( 0, "aaa",buf+12,-538);
- STRTEST( 0, "aaa",buf+15,-540);
- STRTEST( 0, "aaa",buf+18,-542);
- STRTEST( 0, "aaa",buf+21,-534);
+ STRTEST( 0, -1, "aaa",buf+0,-530);
+ STRTEST( 0, -1, "aaa",buf+3,-532);
+ STRTEST( 0, -1, "aaa",buf+6,-534);
+ STRTEST( 0, -1, "aaa",buf+9,-536);
+ STRTEST( 0, -1, "aaa",buf+12,-538);
+ STRTEST( 0, -1, "aaa",buf+15,-540);
+ STRTEST( 0, -1, "aaa",buf+18,-542);
+ STRTEST( 0, 0, "aaa",buf+21,-534);
/* equal, length=4 */
len=4;
- STRTEST( 0, "aaaa","aaaa",-540);
- STRTEST( 0, "aaaa","Aaaa",-542);
- STRTEST( 0, "aaaa","aAaa",-544);
- STRTEST( 0, "aaaa","aaAa",-546);
- STRTEST( 0, "aaaa","aaaA",-548);
- STRTEST( 0, "aaaa","AAaa",-550);
- STRTEST( 0, "aaaa","aAAa",-552);
- STRTEST( 0, "aaaa","aaAA",-554);
- STRTEST( 0, "aaaa","AaAa",-556);
- STRTEST( 0, "aaaa","aAaA",-558);
- STRTEST( 0, "aaaa","AaaA",-560);
- STRTEST( 0, "aaaa","AAAa",-562);
- STRTEST( 0, "aaaa","aAAA",-564);
- STRTEST( 0, "aaaa","AAaA",-566);
- STRTEST( 0, "aaaa","AaAA",-568);
- STRTEST( 0, "aaaa","AAAA",-570);
+ STRTEST( 0, 0, "aaaa","aaaa",-540);
+ STRTEST( 0, 0, "aaaa","Aaaa",-542);
+ STRTEST( 0, 0, "aaaa","aAaa",-544);
+ STRTEST( 0, 0, "aaaa","aaAa",-546);
+ STRTEST( 0, 0, "aaaa","aaaA",-548);
+ STRTEST( 0, 0, "aaaa","AAaa",-550);
+ STRTEST( 0, 0, "aaaa","aAAa",-552);
+ STRTEST( 0, 0, "aaaa","aaAA",-554);
+ STRTEST( 0, 0, "aaaa","AaAa",-556);
+ STRTEST( 0, 0, "aaaa","aAaA",-558);
+ STRTEST( 0, 0, "aaaa","AaaA",-560);
+ STRTEST( 0, 0, "aaaa","AAAa",-562);
+ STRTEST( 0, 0, "aaaa","aAAA",-564);
+ STRTEST( 0, 0, "aaaa","AAaA",-566);
+ STRTEST( 0, 0, "aaaa","AaAA",-568);
+ STRTEST( 0, 0, "aaaa","AAAA",-570);
/* equal, length=5 */
buf = "aaaAa""AaaaA""AaAaA""AAAAA";
len=5;
- STRTEST( 0, "aaaaa",buf+0,-580);
- STRTEST( 0, "aaaaa",buf+5,-582);
- STRTEST( 0, "aaaaa",buf+10,-584);
- STRTEST( 0, "aaaaa",buf+15,-586);
+ STRTEST( 0, -1, "aaaaa",buf+0,-580);
+ STRTEST( 0, -1, "aaaaa",buf+5,-582);
+ STRTEST( 0, -1, "aaaaa",buf+10,-584);
+ STRTEST( 0, 0, "aaaaa",buf+15,-586);
/* not equal, length=1 */
len=1;
- STRTEST( -1, "a", "b", -600);
+ STRTEST( -1, -1, "a", "b", -600);
/* not equal, length=2 */
buf = "ab""ba";
len=2;
- STRTEST( -1, "aa", buf+0, -610);
- STRTEST( -1, "aa", buf+2, -612);
+ STRTEST( -1, -1, "aa", buf+0, -610);
+ STRTEST( -1, -1, "aa", buf+2, -612);
/* not equal, length=3 */
buf = "aab""aba""baa";
len=3;
- STRTEST( -1, "aaa", buf+0, -620);
- STRTEST( -1, "aaa", buf+3, -622);
- STRTEST( -1, "aaa", buf+6, -624);
+ STRTEST( -1, -1, "aaa", buf+0, -620);
+ STRTEST( -1, -1, "aaa", buf+3, -622);
+ STRTEST( -1, -1, "aaa", buf+6, -624);
/* not equal, length=4 */
buf = "aaab""aaba""abaa""baaa";
len=4;
- STRTEST( -1, "aaaa", buf+0, -630);
- STRTEST( -1, "aaaa", buf+4, -632);
- STRTEST( -1, "aaaa", buf+8, -634);
- STRTEST( -1, "aaaa", buf+12, -636);
+ STRTEST( -1, -1, "aaaa", buf+0, -630);
+ STRTEST( -1, -1, "aaaa", buf+4, -632);
+ STRTEST( -1, -1, "aaaa", buf+8, -634);
+ STRTEST( -1, -1, "aaaa", buf+12, -636);
/* not equal, length=5 */
buf="aaaab""aaaba""aabaa""abaaa""baaaa";
len=5;
- STRTEST( -1, "aaaaa", buf+0, -640);
- STRTEST( -1, "aaaaa", buf+5, -642);
- STRTEST( -1, "aaaaa", buf+10, -644);
- STRTEST( -1, "aaaaa", buf+15, -646);
- STRTEST( -1, "aaaaa", buf+20, -648);
+ STRTEST( -1, -1, "aaaaa", buf+0, -640);
+ STRTEST( -1, -1, "aaaaa", buf+5, -642);
+ STRTEST( -1, -1, "aaaaa", buf+10, -644);
+ STRTEST( -1, -1, "aaaaa", buf+15, -646);
+ STRTEST( -1, -1, "aaaaa", buf+20, -648);
zero.u32.hi = zero.u32.lo = 0;
c1 = pj_elapsed_cycle(&zero, &e1);