BUG: An empty regex is not allowed in the POSIX grammar.

Lucas lucas at sexy.is
Mon Apr 20 05:29:10 CEST 2020


Hello hlwm devs,

Am Lucas, and together with Florian, cc'd in this email, we're trying
to port 0.8.0 release to OpenBSD.

The only issue we encountered for building, despite the switch to
CMake, was the one reported in GitHub issue 741, dealt with in commit
b3708561161ca797f1bf16e1f1ee9e5fcc743fbc. Backporting that, it builds
fine. The compiler used for building the package is clang, as it's
the default compiler for the platform (amd64 aka x86-64 in this case):

oolong$ cc --version
OpenBSD clang version 8.0.1 (tags/RELEASE_801/final) (based on LLVM 8.0.1)
Target: amd64-unknown-openbsd6.7
Thread model: posix
InstalledDir: /usr/bin

Now, what it doesn't do finely is running. We get an exception right
away:

terminating with uncaught exception of type std::invalid_argument: An empty regex is not allowed in the POSIX grammar.

After recompiling with -g, we get the following backtrace:

(gdb) bt
#0  thrkill () at -:3
#1  0x000004c0e90197de in _libc_abort () at /usr/src/lib/libc/stdlib/abort.c:51
#2  0x000004c12880206c in abort_message (format=<optimized out>) at /usr/src/lib/libcxxabi/src/abort_message.cpp:77
#3  0x000004c12880233a in demangling_terminate_handler () at /usr/src/lib/libcxxabi/src/cxa_default_handlers.cpp:62
#4  0x000004c1288071ef in std::__terminate (func=0x0) at /usr/src/lib/libcxxabi/src/cxa_handlers.cpp:60
#5  0x000004c12880842c in __cxxabiv1::failed_throw (exception_header=0x4c13982fc00) at /usr/src/lib/libcxxabi/src/cxa_exception.cpp:153
#6  0x000004c12880838b in __cxa_throw (thrown_object=0x4c13982fc80, tinfo=0x4c128825110 <typeinfo for std::invalid_argument>, dest=<optimized out>)
    at /usr/src/lib/libcxxabi/src/cxa_exception.cpp:285
#7  0x000004bea3199cf0 in RegexStr::fromStr (source=...) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/regexstr.cpp:17
#8  0x000004bea316a152 in KeyManager::KeyMask::KeyMask (this=0x4c151c38888)
    at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/keymanager.cpp:244
#9  0x000004bea31b2643 in KeyManager::KeyManager (this=0x4c151c38800) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/keymanager.h:67
#10 0x000004bea31afd4d in Child_<KeyManager>::init<>() (this=<optimized out>) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/child.h:27
#11 Root::Root (this=0x4c19a385818, g=..., xconnection=..., ipcServer=...) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/root.cpp:48
#12 0x000004bea310bcc2 in std::__1::__compressed_pair_elem<Root, 1, false>::__compressed_pair_elem<Globals&, XConnection&, IpcServer&, 0ul, 1ul, 2ul> (
    this=<optimized out>, __args=<error reading variable: access outside bounds of object referenced via synthetic pointer>) at /usr/include/c++/v1/memory:2156
#13 std::__1::__compressed_pair<std::__1::allocator<Root>, Root>::__compressed_pair<std::__1::allocator<Root>&, Globals&, XConnection&, IpcServer&> (
    this=<optimized out>, __first_args=..., __second_args=<error reading variable: access outside bounds of object referenced via synthetic pointer>, __pc=...)
    at /usr/include/c++/v1/memory:2259
#14 std::__1::__shared_ptr_emplace<Root, std::__1::allocator<Root> >::__shared_ptr_emplace<Globals&, XConnection&, IpcServer&> (this=0x4c19a385800, __args=..., 
    __args=..., __args=..., __a=...) at /usr/include/c++/v1/memory:3672
#15 std::__1::shared_ptr<Root>::make_shared<Globals&, XConnection&, IpcServer&> (__args=..., __args=..., __args=...) at /usr/include/c++/v1/memory:4331
#16 std::__1::make_shared<Root, Globals&, XConnection&, IpcServer&> (__args=..., __args=..., __args=...) at /usr/include/c++/v1/memory:4710
#17 main (argc=<optimized out>, argv=0x7f7fffff1148) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/main.cpp:506

As the backtrace shows, the problem arise in RegexStr::fromStr, in
particular, with RegexStr::fromStr(""). This was introduces in 3 places
addressing issue 716 (commit 9e03ab0088b96045e688159ecffc5a9975a91ad5)
and issue 717 (commit 73c5b788e00ea3daca5b474574683999b7f4496e).

Now, RegexStr::fromStr creates a POSIX Extended Regular Expression from
the string passed. According to POSIX[1], an ERE can't be empty. In this
regard, OpenBSD is doing the technically correct thing, but it renders
hlwm useless!

Following this email is a diff for changing "" into "^$", which is my
guess of what the author meant to express with an empty regex. My
interpretation might be incorrect, or empty strings might want to be
deal with directly inside fromStr. This is just a proposed approach.

-Lucas

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_05_03


-------------- next part --------------
From 9867797039dc494e76bf9d1527b0fb91a9825df7 Mon Sep 17 00:00:00 2001
Message-Id: <9867797039dc494e76bf9d1527b0fb91a9825df7.1587354677.git.lucas at sexy.is>
From: Lucas <lucas at sexy.is>
Date: Mon, 20 Apr 2020 03:26:05 +0000
Subject: [PATCH] POSIX doesn't allow empty EREs

This triggers an exception at least in OpenBSD with clang:

    terminating with uncaught exception of type std::invalid_argument: An empty regex is not allowed in the POSIX grammar.

    (gdb) bt
    #0  thrkill () at -:3
    #1  0x000004c0e90197de in _libc_abort () at /usr/src/lib/libc/stdlib/abort.c:51
    #2  0x000004c12880206c in abort_message (format=<optimized out>) at /usr/src/lib/libcxxabi/src/abort_message.cpp:77
    #3  0x000004c12880233a in demangling_terminate_handler () at /usr/src/lib/libcxxabi/src/cxa_default_handlers.cpp:62
    #4  0x000004c1288071ef in std::__terminate (func=0x0) at /usr/src/lib/libcxxabi/src/cxa_handlers.cpp:60
    #5  0x000004c12880842c in __cxxabiv1::failed_throw (exception_header=0x4c13982fc00) at /usr/src/lib/libcxxabi/src/cxa_exception.cpp:153
    #6  0x000004c12880838b in __cxa_throw (thrown_object=0x4c13982fc80, tinfo=0x4c128825110 <typeinfo for std::invalid_argument>, dest=<optimized out>)
        at /usr/src/lib/libcxxabi/src/cxa_exception.cpp:285
    #7  0x000004bea3199cf0 in RegexStr::fromStr (source=...) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/regexstr.cpp:17
    #8  0x000004bea316a152 in KeyManager::KeyMask::KeyMask (this=0x4c151c38888)
        at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/keymanager.cpp:244
    #9  0x000004bea31b2643 in KeyManager::KeyManager (this=0x4c151c38800) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/keymanager.h:67
    #10 0x000004bea31afd4d in Child_<KeyManager>::init<>() (this=<optimized out>) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/child.h:27
    #11 Root::Root (this=0x4c19a385818, g=..., xconnection=..., ipcServer=...) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/root.cpp:48
    #12 0x000004bea310bcc2 in std::__1::__compressed_pair_elem<Root, 1, false>::__compressed_pair_elem<Globals&, XConnection&, IpcServer&, 0ul, 1ul, 2ul> (
        this=<optimized out>, __args=<error reading variable: access outside bounds of object referenced via synthetic pointer>) at /usr/include/c++/v1/memory:2156
    #13 std::__1::__compressed_pair<std::__1::allocator<Root>, Root>::__compressed_pair<std::__1::allocator<Root>&, Globals&, XConnection&, IpcServer&> (
        this=<optimized out>, __first_args=..., __second_args=<error reading variable: access outside bounds of object referenced via synthetic pointer>, __pc=...)
        at /usr/include/c++/v1/memory:2259
    #14 std::__1::__shared_ptr_emplace<Root, std::__1::allocator<Root> >::__shared_ptr_emplace<Globals&, XConnection&, IpcServer&> (this=0x4c19a385800, __args=...,
        __args=..., __args=..., __a=...) at /usr/include/c++/v1/memory:3672
    #15 std::__1::shared_ptr<Root>::make_shared<Globals&, XConnection&, IpcServer&> (__args=..., __args=..., __args=...) at /usr/include/c++/v1/memory:4331
    #16 std::__1::make_shared<Root, Globals&, XConnection&, IpcServer&> (__args=..., __args=..., __args=...) at /usr/include/c++/v1/memory:4710
    #17 main (argc=<optimized out>, argv=0x7f7fffff1148) at /home/lucas/code/openbsd/ports/pobj/herbstluftwm-0.8.0/herbstluftwm-0.8.0/src/main.cpp:506
---
 src/client.cpp     | 4 ++--
 src/keymanager.cpp | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/client.cpp b/src/client.cpp
index e9b7f0d..33c67d4 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -41,8 +41,8 @@ Client::Client(Window window, bool visible_already, ClientManager& cm)
     , title_(this,  "title", "")
     , tag_str_(this,  "tag", &Client::tagName)
     , window_id_str(this,  "winid", "")
-    , keyMask_(this,  "keymask", RegexStr::fromStr(""))
-    , keysInactive_(this,  "keys_inactive", RegexStr::fromStr(""))
+    , keyMask_(this,  "keymask", RegexStr::fromStr("^$"))
+    , keysInactive_(this,  "keys_inactive", RegexStr::fromStr("^$"))
     , pid_(this,  "pid", -1)
     , pseudotile_(this,  "pseudotile", false)
     , ewmhrequests_(this, "ewmhrequests", true)
diff --git a/src/keymanager.cpp b/src/keymanager.cpp
index 6b1232f..e8b6b35 100644
--- a/src/keymanager.cpp
+++ b/src/keymanager.cpp
@@ -249,7 +249,7 @@ KeyManager::KeyMask::KeyMask(const RegexStr &regex, bool negated)
 }
 
 KeyManager::KeyMask::KeyMask()
-    : regex_(RegexStr::fromStr(""))
+    : regex_(RegexStr::fromStr("^$"))
     , negated_(false)
 {
 }
-- 
2.26.1



More information about the hlwm mailing list