From owner-svn-src-head@freebsd.org Fri Aug 19 04:30:31 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C1891BBD7B4; Fri, 19 Aug 2016 04:30:31 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 73D351997; Fri, 19 Aug 2016 04:30:31 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u7J4UUwq025925; Fri, 19 Aug 2016 04:30:30 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u7J4UTqU025924; Fri, 19 Aug 2016 04:30:29 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201608190430.u7J4UTqU025924@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Fri, 19 Aug 2016 04:30:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r304443 - head/sys/cam X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Aug 2016 04:30:31 -0000 Author: imp Date: Fri Aug 19 04:30:29 2016 New Revision: 304443 URL: https://svnweb.freebsd.org/changeset/base/304443 Log: Improve the pattern matching so that internal *'s work, as well as [set] notation. This fixes pattern matching for recently added drives that would set the NCQ Trim being broken incorrectly. PR: 210686 Tested-by: Tomoaki AOKI MFC After: 3 days Modified: head/sys/cam/cam.c Modified: head/sys/cam/cam.c ============================================================================== --- head/sys/cam/cam.c Fri Aug 19 04:21:16 2016 (r304442) +++ head/sys/cam/cam.c Fri Aug 19 04:30:29 2016 (r304443) @@ -207,32 +207,72 @@ cam_strvis_sbuf(struct sbuf *sb, const u /* * Compare string with pattern, returning 0 on match. * Short pattern matches trailing blanks in name, - * wildcard '*' in pattern matches rest of name, - * wildcard '?' matches a single non-space character. + * Shell globbing rules apply: * matches 0 or more characters, + * ? matchces one character, [...] denotes a set to match one char, + * [^...] denotes a complimented set to match one character. + * Spaces in str used to match anything in the pattern string + * but was removed because it's a bug. No current patterns require + * it, as far as I know, but it's impossible to know what drives + * returned. + * + * Each '*' generates recursion, so keep the number of * in check. */ int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len) { - while (*pattern != '\0'&& str_len > 0) { - + while (*pattern != '\0' && str_len > 0) { if (*pattern == '*') { - return (0); - } - if ((*pattern != *str) - && (*pattern != '?' || *str == ' ')) { + pattern++; + if (*pattern == '\0') + return (0); + do { + if (cam_strmatch(str, pattern, str_len) == 0) + return (0); + str++; + str_len--; + } while (str_len > 0); return (1); + } else if (*pattern == '[') { + int negate_range, ok; + uint8_t pc, sc; + + ok = 0; + sc = *str++; + str_len--; + if ((negate_range = (*pattern == '^')) != 0) + pattern++; + while (((pc = *pattern) != ']') && *pattern != '\0') { + pattern++; + if (*pattern == '-') { + if (pattern[1] == '\0') /* Bad pattern */ + return (1); + if (sc >= pc && sc <= pattern[1]) + ok = 1; + pattern += 2; + } else if (pc == sc) + ok = 1; + } + if (ok == negate_range) + return (1); + } else if (*pattern == '?') { + /* NB: || *str == ' ' of the old code is a bug and was removed */ + /* if you add it back, keep this the last if before the naked else */ + pattern++; + str++; + str_len--; + } else { + if (*str != *pattern) + return (1); + pattern++; + str++; + str_len--; } - pattern++; - str++; - str_len--; } while (str_len > 0 && *str == ' ') { str++; str_len--; } - if (str_len > 0 && *str == 0) - str_len = 0; return (str_len); }