summary refs log tree commit diff stats
path: root/src/common/util.c
diff options
context:
space:
mode:
authorJoseph Bisch <joseph.bisch@gmail.com>2017-09-19 14:31:48 -0400
committerTingPing <tingping@tingping.se>2017-09-19 14:31:48 -0400
commit4a09ce6fc3687616d6861ec9f016c4d3e41aba2e (patch)
tree6778d99b9878ef72b8624363adb3b134102601b8 /src/common/util.c
parentf4a592c4f0364d35068bca9f2634946750340356 (diff)
Fix rfc_{n,}casecmp functions (#2058)
rfc_casecmp was broken because reaching terminator for str1 was used as
a terminal condition and str2 may be shorter than str1, resulting in an
oob read condition for str2.

rfc_ncasecmp was broken because it checked if n characters were checked
or if BOTH pointers reached their terminator, however the strings may
be different lengths and also less than n characters in length, meaning
that they don't both reach their terminators at the same time,
resulting in an oob read condition.
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c55
1 files changed, 23 insertions, 32 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 6c665dbc..e61298ab 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1018,53 +1018,44 @@ make_ping_time (void)
 	return (timev.tv_sec - 50000) * 1000 + timev.tv_usec/1000;
 }
 
-
-/************************************************************************
- *    This technique was borrowed in part from the source code to 
- *    ircd-hybrid-5.3 to implement case-insensitive string matches which
- *    are fully compliant with Section 2.2 of RFC 1459, the copyright
- *    of that code being (C) 1990 Jarkko Oikarinen and under the GPL.
- *    
- *    A special thanks goes to Mr. Okarinen for being the one person who
- *    seems to have ever noticed this section in the original RFC and
- *    written code for it.  Shame on all the rest of you (myself included).
- *    
- *        --+ Dagmar d'Surreal
- */
-
 int
 rfc_casecmp (const char *s1, const char *s2)
 {
-	register unsigned char *str1 = (unsigned char *) s1;
-	register unsigned char *str2 = (unsigned char *) s2;
-	register int res;
+	int c1, c2;
 
-	while ((res = rfc_tolower (*str1) - rfc_tolower (*str2)) == 0)
+	while (*s1 && *s2)
 	{
-		if (*str1 == '\0')
-			return 0;
-		str1++;
-		str2++;
+		c1 = (int)rfc_tolower (*s1);
+		c2 = (int)rfc_tolower (*s2);
+		if (c1 != c2)
+			return (c1 - c2);
+		s1++;
+		s2++;
 	}
-	return (res);
+	return (((int)*s1) - ((int)*s2));
 }
 
 int
-rfc_ncasecmp (char *str1, char *str2, int n)
+rfc_ncasecmp (char *s1, char *s2, int n)
 {
-	register unsigned char *s1 = (unsigned char *) str1;
-	register unsigned char *s2 = (unsigned char *) str2;
-	register int res;
+	int c1, c2;
 
-	while ((res = rfc_tolower (*s1) - rfc_tolower (*s2)) == 0)
+	while (*s1 && *s2)
 	{
+		if (n == 0)
+			return 0;
+
+		c1 = (int)rfc_tolower (*s1);
+		c2 = (int)rfc_tolower (*s2);
+		if (c1 != c2)
+			return (c1 - c2);
+		n--;
 		s1++;
 		s2++;
-		n--;
-		if (n == 0 || (*s1 == '\0' && *s2 == '\0'))
-			return 0;
 	}
-	return (res);
+	c1 = (int)rfc_tolower (*s1);
+	c2 = (int)rfc_tolower (*s2);
+	return (c1 - c2);
 }
 
 const unsigned char rfc_tolowertab[] =