From 18d142f3bfc9f59cecb4e6d65013da8c8cdccb65 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 14 Sep 2026 18:34:49 +0200 Subject: [PATCH] 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 --- ucm2/USB-Audio/USB-Audio.conf | 2 +- ucm2/sof-soundwire/sof-soundwire.conf | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 { -- 2.52.0