nixos/xserver: Properly validate XKB options
Checking the keyboard layout has been a long set of hurdles so far, with
several attempts. Originally, the checking was introduced by @lheckemann
in #23709.
The initial implementation just was trying to check whether the symbols/
directory contained the layout name.
Unfortunately, that wasn't enough and keyboard variants weren't
recognized, so if you set layout to eg. "dvorak" it will fail with an
error (#25526).
So my improvement on that was to use sed to filter rules/base.lst and
match the layout against that. I fucked up twice with this, first
because layout can be a comma-separated list which I didn't account for
and second because I ran into a Nix issue (NixOS/nix#1426).
After fixing this, it still wasn't enough (and this is btw. what
localectl also does), because we were *only* matching rules but not
symbols, so using "eu" as a layout won't work either.
I decided now it's the time to actually use libxkbcommon to try
compiling the keyboard options and see whether it succeeds. This comes
in the form of a helper tool called xkbvalidate.
IMHO this approach is a lot less error-prone and we can be sure that we
don't forget about anything because that's what the X server itself uses
to compile the keymap.
Another advantage of this is that we now validate the full set of XKB
options rather than just the layout.
Tested this against a variety of wrong and correct keyboard
configurations and against the "keymap" NixOS VM tests.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @lheckemann, @peti, @7c6f434c, @tohl, @vcunat, @lluchs
Fixes: #27597
2017-07-28 12:36:48 +02:00
|
|
|
{ lib, runCommandCC, libxkbcommon }:
|
|
|
|
|
|
|
|
runCommandCC "xkbvalidate" {
|
|
|
|
buildInputs = [ libxkbcommon ];
|
|
|
|
meta = {
|
|
|
|
description = "NixOS tool to validate X keyboard configuration";
|
|
|
|
license = lib.licenses.mit;
|
xkbvalidate: Don't rely on GNU extensions
The only reason why I was using _GNU_SOURCE was because of vasprintf(),
so getting rid of that extension should make the source way more
portable.
When using vsnprintf() with a null pointer for the output buffer and a
size of 0, I wasn't quite sure whether this would be undefined
behaviour, so I looked it up in the C11 standard.
In section 7.21.6.5, it explicitly mentions this case, so we're lucky:
If n is zero, nothing is written, and s may be a null pointer.
Additionally, section 7.21.6.12 writes the following about vsnprintf():
The vsnprintf function does not invoke the va_end macro.
So to be sure to avoid undefined behaviour I subsequently added the
corresponding va_end() calls.
With this, the platforms attribute is now "unix", because the program
should now even run on OS X, even though it usually wouldn't be needed.
Signed-off-by: aszlig <aszlig@nix.build>
2019-08-15 00:06:51 +02:00
|
|
|
platforms = lib.platforms.unix;
|
nixos/xserver: Properly validate XKB options
Checking the keyboard layout has been a long set of hurdles so far, with
several attempts. Originally, the checking was introduced by @lheckemann
in #23709.
The initial implementation just was trying to check whether the symbols/
directory contained the layout name.
Unfortunately, that wasn't enough and keyboard variants weren't
recognized, so if you set layout to eg. "dvorak" it will fail with an
error (#25526).
So my improvement on that was to use sed to filter rules/base.lst and
match the layout against that. I fucked up twice with this, first
because layout can be a comma-separated list which I didn't account for
and second because I ran into a Nix issue (NixOS/nix#1426).
After fixing this, it still wasn't enough (and this is btw. what
localectl also does), because we were *only* matching rules but not
symbols, so using "eu" as a layout won't work either.
I decided now it's the time to actually use libxkbcommon to try
compiling the keyboard options and see whether it succeeds. This comes
in the form of a helper tool called xkbvalidate.
IMHO this approach is a lot less error-prone and we can be sure that we
don't forget about anything because that's what the X server itself uses
to compile the keymap.
Another advantage of this is that we now validate the full set of XKB
options rather than just the layout.
Tested this against a variety of wrong and correct keyboard
configurations and against the "keymap" NixOS VM tests.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @lheckemann, @peti, @7c6f434c, @tohl, @vcunat, @lluchs
Fixes: #27597
2017-07-28 12:36:48 +02:00
|
|
|
maintainers = [ lib.maintainers.aszlig ];
|
|
|
|
};
|
|
|
|
} ''
|
|
|
|
mkdir -p "$out/bin"
|
xkbvalidate: Don't rely on GNU extensions
The only reason why I was using _GNU_SOURCE was because of vasprintf(),
so getting rid of that extension should make the source way more
portable.
When using vsnprintf() with a null pointer for the output buffer and a
size of 0, I wasn't quite sure whether this would be undefined
behaviour, so I looked it up in the C11 standard.
In section 7.21.6.5, it explicitly mentions this case, so we're lucky:
If n is zero, nothing is written, and s may be a null pointer.
Additionally, section 7.21.6.12 writes the following about vsnprintf():
The vsnprintf function does not invoke the va_end macro.
So to be sure to avoid undefined behaviour I subsequently added the
corresponding va_end() calls.
With this, the platforms attribute is now "unix", because the program
should now even run on OS X, even though it usually wouldn't be needed.
Signed-off-by: aszlig <aszlig@nix.build>
2019-08-15 00:06:51 +02:00
|
|
|
$CC -std=c11 -Wall -pedantic -lxkbcommon ${./xkbvalidate.c} \
|
2019-08-15 01:11:32 +02:00
|
|
|
-o "$out/bin/xkbvalidate"
|
nixos/xserver: Properly validate XKB options
Checking the keyboard layout has been a long set of hurdles so far, with
several attempts. Originally, the checking was introduced by @lheckemann
in #23709.
The initial implementation just was trying to check whether the symbols/
directory contained the layout name.
Unfortunately, that wasn't enough and keyboard variants weren't
recognized, so if you set layout to eg. "dvorak" it will fail with an
error (#25526).
So my improvement on that was to use sed to filter rules/base.lst and
match the layout against that. I fucked up twice with this, first
because layout can be a comma-separated list which I didn't account for
and second because I ran into a Nix issue (NixOS/nix#1426).
After fixing this, it still wasn't enough (and this is btw. what
localectl also does), because we were *only* matching rules but not
symbols, so using "eu" as a layout won't work either.
I decided now it's the time to actually use libxkbcommon to try
compiling the keyboard options and see whether it succeeds. This comes
in the form of a helper tool called xkbvalidate.
IMHO this approach is a lot less error-prone and we can be sure that we
don't forget about anything because that's what the X server itself uses
to compile the keymap.
Another advantage of this is that we now validate the full set of XKB
options rather than just the layout.
Tested this against a variety of wrong and correct keyboard
configurations and against the "keymap" NixOS VM tests.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Cc: @lheckemann, @peti, @7c6f434c, @tohl, @vcunat, @lluchs
Fixes: #27597
2017-07-28 12:36:48 +02:00
|
|
|
''
|