From nobody Wed Sep 25 20:43:40 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 4XDTGN3PNCz5Xh7b; Wed, 25 Sep 2024 20:43:40 +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 4XDTGN2wxWz57hF; Wed, 25 Sep 2024 20:43:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727297020; 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=FnISa9ytgg+lV8TNpbUfXZG0FGmnDUx6H/8vFcYHedw=; b=b15GTIcM/sVieR4VODY+nadUZGU6RpxdvdfqJtrFNM1woW2+mptJB/Q8tWASssqORPB8BW zM/3/VhLAhJw84uJ9DdOao2IqgCU3psZEC2jRbkTV/BpTn2mRV4z6a5g+oWVdF1bX4tesk 0SkRoWu5bLmGYK9u+MCkoXfbAAR4KqfVERLmn6OS5OdyLE8LzbeX8r6L9K0n3h9XFIjCq7 TbkBzgYdysjrbt3dXybgoZkDxUDIW3VRdV0CrcuR6JUD37f1Zt4mVZrf4x66L1UfySmvv9 1L2Fl0QHz/qftCZhTwrIY4P9eoYwLiwLnqNpxKy3BzqYBiTnMyn1AZV3wZL8cA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727297020; 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=FnISa9ytgg+lV8TNpbUfXZG0FGmnDUx6H/8vFcYHedw=; b=j3kNtMwVnU3p43/NCxi5YYCBwaDzzW/mizzfAn9g77WhNnQjiJn0FuHfnl9TcIM7vuV/On b7EALs4vK0sYduY+Lbt5FJToaQlOfCxduY3atkZVjY1wf+BUZZB3Di5TRVTJQYi8pYR1gX Mgt/+M8CW/5PyDWp7m5HafqAeMS/dkU6kWI276X6ruX+p8G7EWsmpnyT+GlLTcvqxlWV1r hcFQ4B0XEoY6IfmsrsASjXZkOJqlNFKMzxUTuTbjm6hvSjUWDDlhKoVmDOFAzixqm8jGUp CDItp+aM02mPs4fZto1L7CYlZmVBrUY7/xnYgyTcI9JXOg9lvkN5MCeb7enK2g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1727297020; a=rsa-sha256; cv=none; b=WRwGK2sAhhmcd9wdU4zwhTKvFzG3WG1Q/Oan0m/lTqG4XzDfE+zCjBiR+s05d8n1f+4MO/ PFRHJCEcSTykC5orEMJhPacBAx23nPyvvDz8ZhKMQExDP0vTUsfVH7rBSG4uL3Nwd/OQ/d rpWCzR3CpNDFIJKUjhI1ugxV0lFmVPG/4JLCov/1S0QnmXV+N8585JsgNBmN+j1EyM4Xkm Mx5bb0aEaIkuN8Oqy80Eei/qW+4OOo+LJxtqJWTLjS0O7oSCSgIgnZfiO9Ky5/7Ja8/QwG +4f2EahOs27yCrml+q72c0w896I0FpsyZNhpwsZ66HJ3ievYtVm4Sr3Kdow33A== 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 4XDTGN2Y9JzS9M; Wed, 25 Sep 2024 20:43:40 +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 48PKheeb003478; Wed, 25 Sep 2024 20:43:40 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 48PKhett003475; Wed, 25 Sep 2024 20:43:40 GMT (envelope-from git) Date: Wed, 25 Sep 2024 20:43:40 GMT Message-Id: <202409252043.48PKhett003475@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: d96ce6d00070 - stable/13 - 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/13 X-Git-Reftype: branch X-Git-Commit: d96ce6d000703f3f57d9214b741e16cc7741d77e Auto-Submitted: auto-generated The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=d96ce6d000703f3f57d9214b741e16cc7741d77e commit d96ce6d000703f3f57d9214b741e16cc7741d77e Author: Bill Sommerfeld AuthorDate: 2023-12-21 03:46:14 +0000 Commit: Kyle Evans CommitDate: 2024-09-25 20:42:28 +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 42fa1b99e58e..2897052fa0f8 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -1592,17 +1592,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 }