[svn-commits] tilghman: branch 1.6.2 r229366 - in /branches/1.6.2: ./ main/pbx.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Nov 10 16:17:40 CST 2009


Author: tilghman
Date: Tue Nov 10 16:17:34 2009
New Revision: 229366

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=229366
Log:
Merged revisions 229361 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r229361 | tilghman | 2009-11-10 16:14:22 -0600 (Tue, 10 Nov 2009) | 19 lines
  
  Merged revisions 229360 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r229360 | tilghman | 2009-11-10 16:09:16 -0600 (Tue, 10 Nov 2009) | 12 lines
    
    If two pattern classes start with the same digit and have the same number of characters, they will compare equal.
    The example given in the issue report is that of [234] and [246], which have
    these characteristics, yet they are clearly not equivalent.  The code still
    uses these two characteristics, yet when the two scores compare equal, an
    additional check will be done to compare all characters within the class to
    verify equality.
    (closes issue #15421)
     Reported by: jsmith
     Patches: 
           20091109__issue15421__2.diff.txt uploaded by tilghman (license 14)
     Tested by: jsmith, thedavidfactor
  ........
................

Modified:
    branches/1.6.2/   (props changed)
    branches/1.6.2/main/pbx.c

Propchange: branches/1.6.2/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.2/main/pbx.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.2/main/pbx.c?view=diff&rev=229366&r1=229365&r2=229366
==============================================================================
--- branches/1.6.2/main/pbx.c (original)
+++ branches/1.6.2/main/pbx.c Tue Nov 10 16:17:34 2009
@@ -2093,9 +2093,8 @@
  *	   we could encode the special cases as 0xffXX where XX
  *	   is 1, 2, 3, 4 as used above.
  */
-static int ext_cmp1(const char **p)
-{
-	uint32_t chars[8];
+static int ext_cmp1(const char **p, unsigned char *bitwise)
+{
 	int c, cmin = 0xff, count = 0;
 	const char *end;
 
@@ -2103,6 +2102,7 @@
 	 * a valid character.
 	 */
 	c = *(*p)++;
+	memset(bitwise, 0xff, 32);
 
 	/* always return unless we have a set of chars */
 	switch (toupper(c)) {
@@ -2110,12 +2110,19 @@
 		return 0x0000 | (c & 0xff);
 
 	case 'N':	/* 2..9 */
-		return 0x0800 | '2' ;
+		bitwise[6] = 0x01;
+		bitwise[7] = 0xfe;
+		return 0x0800 | '2';
 
 	case 'X':	/* 0..9 */
+		bitwise[5] = 0x7f;
+		bitwise[6] = 0x00;
+		bitwise[7] = 0xfe;
 		return 0x0A00 | '0';
 
 	case 'Z':	/* 1..9 */
+		bitwise[6] = 0x00;
+		bitwise[7] = 0xfe;
 		return 0x0900 | '1';
 
 	case '.':	/* wildcard */
@@ -2139,22 +2146,28 @@
 		return 0x40000;	/* XXX make this entry go last... */
 	}
 
-	memset(chars, '\0', sizeof(chars));	/* clear all chars in the set */
 	for (; *p < end  ; (*p)++) {
 		unsigned char c1, c2;	/* first-last char in range */
 		c1 = (unsigned char)((*p)[0]);
 		if (*p + 2 < end && (*p)[1] == '-') { /* this is a range */
 			c2 = (unsigned char)((*p)[2]);
-			*p += 2;	/* skip a total of 3 chars */
-		} else			/* individual character */
+			*p += 2;    /* skip a total of 3 chars */
+		} else {        /* individual character */
 			c2 = c1;
-		if (c1 < cmin)
+		}
+		if (c1 < cmin) {
 			cmin = c1;
+		}
 		for (; c1 <= c2; c1++) {
-			uint32_t mask = 1 << (c1 % 32);
-			if ( (chars[ c1 / 32 ] & mask) == 0)
+			unsigned char mask = 1 << (c1 % 8);
+			/* Count the number of characters in the class, discarding duplicates. */
+			if ( (bitwise[ c1 / 8 ] & mask) == 1) {
 				count += 0x100;
-			chars[ c1 / 32 ] |= mask;
+			}
+			/*!\note If two patterns score the same, but one includes '0' (as
+			 * the lowest ASCII value in the given class) and the other does
+			 * not, then the one including '0' will compare as coming first. */
+			bitwise[ c1 / 8 ] &= ~mask;
 		}
 	}
 	(*p)++;
@@ -2168,8 +2181,9 @@
 {
 	/* make sure non-patterns come first.
 	 * If a is not a pattern, it either comes first or
-	 * we use strcmp to compare the strings.
+	 * we do a more complex pattern comparison.
 	 */
+	unsigned char bitwise[2][32];
 	int ret = 0;
 
 	if (a[0] != '_')
@@ -2178,16 +2192,20 @@
 	/* Now we know a is a pattern; if b is not, a comes first */
 	if (b[0] != '_')
 		return 1;
-#if 0	/* old mode for ext matching */
-	return strcmp(a, b);
-#endif
+
 	/* ok we need full pattern sorting routine */
-	while (!ret && a && b)
-		ret = ext_cmp1(&a) - ext_cmp1(&b);
-	if (ret == 0)
+	while (!ret && a && b) {
+		ret = ext_cmp1(&a, bitwise[0]) - ext_cmp1(&b, bitwise[1]);
+		if (ret == 0) {
+			/* Are the classes different, even though they score the same? */
+			ret = memcmp(bitwise[0], bitwise[1], 32);
+		}
+	}
+	if (ret == 0) {
 		return 0;
-	else
+	} else {
 		return (ret > 0) ? 1 : -1;
+	}
 }
 
 int ast_extension_cmp(const char *a, const char *b)




More information about the svn-commits mailing list