From: Jaroslav Kysela Date: Mon, 14 Sep 2026 16:34:49 +0000 (+0200) Subject: ucm2: use locale-agnostic character classes in parsing regexes X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=alsa-ucm-conf.git ucm2: use locale-agnostic character classes in parsing regexes Several UCM configuration regexes parse CardComponents using POSIX bracket *ranges* such as "[a-z0-9]", "[a-z0-9-]" and "[0-9a-f]". Range expressions are locale sensitive: the set of characters covered by "x-y" depends on the current collation order (LC_COLLATE), not on code points. Under the Turkish locale (tr_TR.UTF-8) the dotless/dotted 'i' handling reorders the collation sequence, so "[a-z]" no longer matches every lowercase ASCII letter. As a result the "mic:...-dmic" component in sof-soundwire.conf is truncated (e.g. to "dm"), ALSA then tries to open a non-existent "dm.conf" and the whole UCM import for the SoundWire card aborts, leaving the user with a dummy-only audio profile (no speaker, no microphone). Fix the whole tree by switching to POSIX character classes, which are defined by character classification instead of collation order and thus match the intended ASCII set regardless of the active locale: - sof-soundwire.conf: "[a-z0-9]" -> "[[:alnum:]]", "[a-z0-9-]" -> "[[:alnum:]-]" - USB-Audio.conf: "[0-9a-f]" -> "[[:xdigit:]]" [[:xdigit:]] is used for the USB vendor/device IDs because it matches exactly the hexadecimal digits (and, unlike [[:digit:]], stays restricted to ASCII in glibc). Pure digit ranges such as "[0-9]" are left untouched: digits do not collation-reorder and the range already matches only ASCII digits. Fixes: https://github.com/alsa-project/alsa-ucm-conf/issues/824 Signed-off-by: Jaroslav Kysela --- diff --git a/ucm2/USB-Audio/USB-Audio.conf b/ucm2/USB-Audio/USB-Audio.conf index ea35792..476e679 100644 --- a/ucm2/USB-Audio/USB-Audio.conf +++ b/ucm2/USB-Audio/USB-Audio.conf @@ -8,7 +8,7 @@ Define.ProfileName "" Define.MixerRemap "" Define.SplitPCMPeriodTime 10000 # 10ms DefineRegex.USBID { - Regex "USB([0-9a-f]{4}):([0-9a-f]{4})" + Regex "USB([[:xdigit:]]{4}):([[:xdigit:]]{4})" String "${CardComponents}" } diff --git a/ucm2/sof-soundwire/sof-soundwire.conf b/ucm2/sof-soundwire/sof-soundwire.conf index 95bd28b..d6cb248 100644 --- a/ucm2/sof-soundwire/sof-soundwire.conf +++ b/ucm2/sof-soundwire/sof-soundwire.conf @@ -24,7 +24,7 @@ Define { DefineRegex { SpeakerCodec { - Regex " spk:([a-z0-9]+((-sdca)|(-spk)|(-bridge))?(\\+[a-z0-9]+((-spk)?))?)" + Regex " spk:([[:alnum:]]+((-sdca)|(-spk)|(-bridge))?(\\+[[:alnum:]]+((-spk)?))?)" String "${CardComponents}" } SpeakerChannels { @@ -36,11 +36,11 @@ DefineRegex { String "${CardComponents}" } HeadsetCodec { - Regex " hs:([a-z0-9]+(-sdca)?)" + Regex " hs:([[:alnum:]]+(-sdca)?)" String "${CardComponents}" } MicCodec { - Regex " mic:([a-z0-9]+(-dmic)?+(-sdca)?)" + Regex " mic:([[:alnum:]]+(-dmic)?+(-sdca)?)" String "${CardComponents}" } Mics { @@ -69,7 +69,7 @@ If.old_multi_spk { # for speaker, do codec+amplifier split If.spk_amp_split1.Append.DefineRegex.SpeakerSplit { - Regex "([a-z0-9-]+)\\+([a-z0-9-]+)" + Regex "([[:alnum:]-]+)\\+([[:alnum:]-]+)" String "${var:SpeakerCodec1}" } If.spk_amp_split2 {