Merged revisions 237493 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Mon, 4 Jan 2010 20:59:01 +0000 (20:59 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Mon, 4 Jan 2010 20:59:01 +0000 (20:59 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r237493 | tilghman | 2010-01-04 14:57:35 -0600 (Mon, 04 Jan 2010) | 8 lines

  Regression in issue #15421 - Pattern matching
  (closes issue #16482)
   Reported by: wdoekes
   Patches:
         astsvn-16482-betterfix.diff uploaded by wdoekes (license 717)
         20091223__issue16482.diff.txt uploaded by tilghman (license 14)
   Tested by: wdoekes, tilghman
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@237494 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/pbx.c

index 2acacd2..45e46df 100644 (file)
@@ -2138,31 +2138,28 @@ static int ext_cmp1(const char **p, unsigned char *bitwise)
        int c, cmin = 0xff, count = 0;
        const char *end;
 
        int c, cmin = 0xff, count = 0;
        const char *end;
 
-       /* load, sign extend and advance pointer until we find
-        * a valid character.
-        */
+       /* load value and advance pointer */
        c = *(*p)++;
        c = *(*p)++;
-       memset(bitwise, 0xff, 32);
 
        /* always return unless we have a set of chars */
        switch (toupper(c)) {
        default:        /* ordinary character */
 
        /* always return unless we have a set of chars */
        switch (toupper(c)) {
        default:        /* ordinary character */
-               return 0x0000 | (c & 0xff);
+               bitwise[c / 8] = 1 << (c % 8);
+               return 0x0100 | (c & 0xff);
 
        case 'N':       /* 2..9 */
 
        case 'N':       /* 2..9 */
-               bitwise[6] = 0x01;
-               bitwise[7] = 0xfe;
+               bitwise[6] = 0xfc;
+               bitwise[7] = 0x03;
                return 0x0800 | '2';
 
        case 'X':       /* 0..9 */
                return 0x0800 | '2';
 
        case 'X':       /* 0..9 */
-               bitwise[5] = 0x7f;
-               bitwise[6] = 0x00;
-               bitwise[7] = 0xfe;
+               bitwise[6] = 0xff;
+               bitwise[7] = 0x03;
                return 0x0A00 | '0';
 
        case 'Z':       /* 1..9 */
                return 0x0A00 | '0';
 
        case 'Z':       /* 1..9 */
-               bitwise[6] = 0x00;
-               bitwise[7] = 0xfe;
+               bitwise[6] = 0xfe;
+               bitwise[7] = 0x03;
                return 0x0900 | '1';
 
        case '.':       /* wildcard */
                return 0x0900 | '1';
 
        case '.':       /* wildcard */
@@ -2200,14 +2197,13 @@ static int ext_cmp1(const char **p, unsigned char *bitwise)
                }
                for (; c1 <= c2; c1++) {
                        unsigned char mask = 1 << (c1 % 8);
                }
                for (; c1 <= c2; c1++) {
                        unsigned char mask = 1 << (c1 % 8);
-                       /* Count the number of characters in the class, discarding duplicates. */
-                       if ( (bitwise[ c1 / 8 ] & mask) == 1) {
+                       /*!\note If two patterns score the same, the one with the lowest
+                        * ascii values will compare as coming first. */
+                       /* Flag the character as included (used) and count it. */
+                       if (!(bitwise[ c1 / 8 ] & mask)) {
+                               bitwise[ c1 / 8 ] |= mask;
                                count += 0x100;
                        }
                                count += 0x100;
                        }
-                       /*!\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)++;
                }
        }
        (*p)++;
@@ -2223,7 +2219,6 @@ static int ext_cmp(const char *a, const char *b)
         * If a is not a pattern, it either comes first or
         * we do a more complex pattern comparison.
         */
         * If a is not a pattern, it either comes first or
         * we do a more complex pattern comparison.
         */
-       unsigned char bitwise[2][32];
        int ret = 0;
 
        if (a[0] != '_')
        int ret = 0;
 
        if (a[0] != '_')
@@ -2233,14 +2228,17 @@ static int ext_cmp(const char *a, const char *b)
        if (b[0] != '_')
                return 1;
 
        if (b[0] != '_')
                return 1;
 
-       /* ok we need full pattern sorting routine */
-       while (!ret && a && b) {
+       /* ok we need full pattern sorting routine.
+        * skip past the underscores */
+       ++a; ++b;
+       do {
+               unsigned char bitwise[2][32] = { { 0, } };
                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);
                }
                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);
                }
-       }
+       } while (!ret && a && b);
        if (ret == 0) {
                return 0;
        } else {
        if (ret == 0) {
                return 0;
        } else {