Diff for /embedaddon/smartmontools/utility.cpp between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2013/07/22 01:17:36 version 1.1.1.4, 2013/10/14 07:54:04
Line 364  void syserror(const char *message){ Line 364  void syserror(const char *message){
   return;    return;
 }  }
   
   // Check regular expression for non-portable features.
   //
 // POSIX extended regular expressions interpret unmatched ')' ordinary:  // POSIX extended regular expressions interpret unmatched ')' ordinary:
 // "The close-parenthesis shall be considered special in this context  // "The close-parenthesis shall be considered special in this context
 //  only if matched with a preceding open-parenthesis."  //  only if matched with a preceding open-parenthesis."
 //  //
// Actual '(...)' nesting errors remain undetected on strict POSIX// GNU libc and BSD libc support unmatched ')', Cygwin reports an error.
// implementations (glibc) but an error is reported on others (Cygwin).//
// // POSIX extended regular expressions do not define empty subexpressions:
// The check below is rather incomplete because it does not handle// "A vertical-line appearing first or last in an ERE, or immediately following
// e.g. '\)' '[)]'.//  a vertical-line or a left-parenthesis, or immediately preceding a
// But it should work for the regex subset used in drive database//  right-parenthesis, produces undefined results."
// and smartd '-s' directives.//
static int check_regex_nesting(const char * pattern)// GNU libc and Cygwin support empty subexpressions, BSD libc reports an error.
 //
 static const char * check_regex(const char * pattern)
 {  {
  int level = 0, i;  int level = 0;
  for (i = 0; pattern[i] && level >= 0; i++) {  char c;
    switch (pattern[i]) {
      case '(': level++; break;  for (int i = 0; (c = pattern[i]); i++) {
      case ')': level--; break;    // Skip "\x"
     if (c == '\\') {
       if (!pattern[++i])
         break;
       continue;
     }      }
   
       // Skip "[...]"
       if (c == '[') {
         if (pattern[++i] == '^')
           i++;
         if (!pattern[i++])
           break;
         while ((c = pattern[i]) && c != ']')
           i++;
         if (!c)
           break;
         continue;
       }
   
       // Check "(...)" nesting
       if (c == '(')
         level++;
       else if (c == ')' && --level < 0)
         return "Unmatched ')'";
   
       // Check for leading/trailing '|' or "||", "|)", "|$", "(|", "^|"
       char c1;
       if (   (c == '|' && (   i == 0 || !(c1 = pattern[i+1])
                             || c1 == '|' || c1 == ')' || c1 == '$'))
           || ((c == '(' || c == '^') && pattern[i+1] == '|')       )
         return "Empty '|' subexpression";
   }    }
  return level;
   return (const char *)0;
 }  }
   
 // Wrapper class for regex(3)  // Wrapper class for regex(3)
Line 465  bool regular_expression::compile() Line 500  bool regular_expression::compile()
     return false;      return false;
   }    }
   
  if (check_regex_nesting(m_pattern.c_str()) < 0) {  const char * errmsg = check_regex(m_pattern.c_str());
    m_errmsg = "Unmatched ')'";  if (errmsg) {
     m_errmsg = errmsg;
     free_buf();      free_buf();
     return false;      return false;
   }    }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>