From nobody Wed Sep 25 20:43:34 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XDTGG58G1z5XhM8; Wed, 25 Sep 2024 20:43:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XDTGG4fpnz57KC; Wed, 25 Sep 2024 20:43:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727297014; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ouaQ/BzkOhYszB4umkm/NPnK/zmYwaAcfwEJlpF1+g4=; b=j6IhdhZ/tGsOSwmgl9S5oa83S5+7LmlzksCvuPs6MeXPv90tfw2ULVy5Vkmwz8vrNQX0t1 v7wn3bPJsoaMIkMioqCeAkY+ZXdI3x9tazNZu4NoROYeH0XBaOj8HJqM7beeLbJGLT64X7 hGn+sa1Hv+rQAQWmtZ3UC/PhUOkntfW+ve9zqCxo+uz3JO//VknK47NmrVGa7t5UnL1SOg o42Y473d5HB39FAiLaSLlcvX/AMEOveboa+76kVUGrbKDvvB8kYqia4LHu2etDwql/T8A6 DHEH3jTJ59mqLnN7nAxWdRqmBzyc1kFeVNpR7uVzafyu6Ddp51cpdVJ6023AUA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727297014; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ouaQ/BzkOhYszB4umkm/NPnK/zmYwaAcfwEJlpF1+g4=; b=fFS3Ze2iQNEBK+tr/NfY0aCYjsURTd6JE3QuKu4Vd5c0U8OZTxoJVCDu2ELMazpGm5M6RM 8DxRTMGKFWUV03hd8f3RUHiXs6VMY5ghyU2Xcxxmf/isyPAA1YkZXFLVEANq+Z/VhWZ1wS Gos4zP1SroEF9yziG5AvVwKLOF1HDPO1biaLGfM0+qADa9XqK/z2C0bfPieQcCPeAvKUfF GjpBZjoqybQLjDlRRRiV6zHzElUEhZqiS0QMIQS5lAeeBKQ5zXxPPX163DGA+Pon+84Whn hc17Zhga0N98TTdw+QBdB6WXBCJOxgwZa1YcNmLweRl+NZf0OuwqQ63pWXjveg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1727297014; a=rsa-sha256; cv=none; b=dtrYgEffeP1vEzydABKbJ7U8CmQAC2O1nr4xedR3Qd1TjjeQMAhUlc7vdSOY5PcA+ALlYX H43MR5G7V8Hv/kQdK/ZkFZh/zRkFAnsU0Q/4QwE+LoMYM50BTopMV44FKH1PpbDtfPYgga KUUoffdIqhs4WHSNfzBHQ7zphVoxkvYJAp/AiqRG6NQj8OWtxxGVfOfdQTmcgeklcdi+pf cdkSCoue6RTzFva6xKZWT4t7LW9dnkdBOcn9Wbd7vhE1+KgkqaYgBxw/gXqNS8Q5r+QcJo Oe+O8NGpZ7MtTnQkHeLdaB8MeEazt0PKdq0+h5y3zcLTSZps0SU63rmwoKuJHA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4XDTGG4FsKzS9L; Wed, 25 Sep 2024 20:43:34 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 48PKhYHE003321; Wed, 25 Sep 2024 20:43:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 48PKhYeD003318; Wed, 25 Sep 2024 20:43:34 GMT (envelope-from git) Date: Wed, 25 Sep 2024 20:43:34 GMT Message-Id: <202409252043.48PKhYeD003318@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: 4f4860c9b07c - stable/14 - regex: mixed sets are misidentified as singletons List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 4f4860c9b07cc10cb6acbe6fbd71db45e344d2e6 Auto-Submitted: auto-generated The branch stable/14 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=4f4860c9b07cc10cb6acbe6fbd71db45e344d2e6 commit 4f4860c9b07cc10cb6acbe6fbd71db45e344d2e6 Author: Bill Sommerfeld AuthorDate: 2023-12-21 03:46:14 +0000 Commit: Kyle Evans CommitDate: 2024-09-25 20:42:25 +0000 regex: mixed sets are misidentified as singletons Fix "singleton" function used by regcomp() to turn character set matches into exact character matches if a character set has exactly one element. The underlying cset representation is complex; most critically it records"small" characters (codepoint less than either 128 or 256 depending on locale) in a bit vector, and "wide" characters in a secondary array. Unfortunately the "singleton" function uses to identify singleton sets treated a cset as a singleton if either the "small" or the "wide" sets had exactly one element (it would then ignore the other set). The easiest way to demonstrate this bug: $ export LANG=C.UTF-8 $ echo 'a' | grep '[abà]' It should match (and print "a") but instead it doesn't match because the single accented character in the set is misinterpreted as a singleton. PR: 281710 Reviewed by: kevans, yuripv Obtained from: illumos (cherry picked from commit 8f7ed58a15556bf567ff876e1999e4fe4d684e1d) --- lib/libc/regex/regcomp.c | 25 ++++++++++++++++++----- lib/libc/tests/regex/multibyte.sh | 43 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index 55f96a2ccbd2..eae4d02657e8 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -1591,17 +1591,32 @@ singleton(cset *cs) { wint_t i, s, n; + /* Exclude the complicated cases we don't want to deal with */ + if (cs->nranges != 0 || cs->ntypes != 0 || cs->icase != 0) + return (OUT); + + if (cs->nwides > 1) + return (OUT); + + /* Count the number of characters present in the bitmap */ for (i = n = 0; i < NC; i++) if (CHIN(cs, i)) { n++; s = i; } - if (n == 1) - return (s); - if (cs->nwides == 1 && cs->nranges == 0 && cs->ntypes == 0 && - cs->icase == 0) + + if (n > 1) + return (OUT); + + if (n == 1) { + if (cs->nwides == 0) + return (s); + else + return (OUT); + } + if (cs->nwides == 1) return (cs->wides[0]); - /* Don't bother handling the other cases. */ + return (OUT); } diff --git a/lib/libc/tests/regex/multibyte.sh b/lib/libc/tests/regex/multibyte.sh index a736352bf0a2..18323f500a2b 100755 --- a/lib/libc/tests/regex/multibyte.sh +++ b/lib/libc/tests/regex/multibyte.sh @@ -1,4 +1,3 @@ - atf_test_case bmpat bmpat_head() { @@ -45,8 +44,50 @@ icase_body() echo $c | atf_check -o "inline:$c\n" sed -ne "/$a/Ip" } +atf_test_case mbset cleanup +mbset_head() +{ + atf_set "descr" "Check multibyte sets matching" +} +mbset_body() +{ + export LC_CTYPE="C.UTF-8" + + # This involved an erroneously implemented optimization which reduces + # single-element sets to an exact match with a single codepoint. + # Match sets record small-codepoint characters in a bitmap and + # large-codepoint characters in an array; the optimization would falsely + # trigger if either the bitmap or the array was a singleton, ignoring + # the members of the other side of the set. + # + # To exercise this, we construct sets which have one member of one side + # and one or more of the other, and verify that all members can be + # found. + printf "a" > mbset; atf_check -o not-empty sed -ne '/[aà]/p' mbset + printf "à" > mbset; atf_check -o not-empty sed -ne '/[aà]/p' mbset + printf "a" > mbset; atf_check -o not-empty sed -ne '/[aàá]/p' mbset + printf "à" > mbset; atf_check -o not-empty sed -ne '/[aàá]/p' mbset + printf "á" > mbset; atf_check -o not-empty sed -ne '/[aàá]/p' mbset + printf "à" > mbset; atf_check -o not-empty sed -ne '/[abà]/p' mbset + printf "a" > mbset; atf_check -o not-empty sed -ne '/[abà]/p' mbset + printf "b" > mbset; atf_check -o not-empty sed -ne '/[abà]/p' mbset + printf "a" > mbset; atf_check -o not-empty sed -Ene '/[aà]/p' mbset + printf "à" > mbset; atf_check -o not-empty sed -Ene '/[aà]/p' mbset + printf "a" > mbset; atf_check -o not-empty sed -Ene '/[aàá]/p' mbset + printf "à" > mbset; atf_check -o not-empty sed -Ene '/[aàá]/p' mbset + printf "á" > mbset; atf_check -o not-empty sed -Ene '/[aàá]/p' mbset + printf "à" > mbset; atf_check -o not-empty sed -Ene '/[abà]/p' mbset + printf "a" > mbset; atf_check -o not-empty sed -Ene '/[abà]/p' mbset + printf "b" > mbset; atf_check -o not-empty sed -Ene '/[abà]/p' mbset +} +mbset_cleanup() +{ + rm -f mbset +} + atf_init_test_cases() { atf_add_test_case bmpat atf_add_test_case icase + atf_add_test_case mbset }