]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[console] Fix definition of unreachability for remapped keys
authorMichael Brown <mcb30@ipxe.org>
Tue, 15 Feb 2022 16:41:19 +0000 (16:41 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 15 Feb 2022 16:46:58 +0000 (16:46 +0000)
The AltGr remapping table is constructed to include only keys that are
not reachable after applying the basic remapping table.  The logic
currently fails to include keys that are omitted entirely from the
basic remapping table since they would map to a non-ASCII character.

Fix this logic by allowing the remapping tables to include null
mappings, which are then elided only at the point of constructing the
C code fragment.

Reported-by: Christian Nilsson <nikize@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
19 files changed:
src/hci/keymap/keymap_al.c
src/hci/keymap/keymap_cf.c
src/hci/keymap/keymap_cz.c
src/hci/keymap/keymap_de.c
src/hci/keymap/keymap_dk.c
src/hci/keymap/keymap_es.c
src/hci/keymap/keymap_et.c
src/hci/keymap/keymap_fi.c
src/hci/keymap/keymap_fr.c
src/hci/keymap/keymap_hu.c
src/hci/keymap/keymap_it.c
src/hci/keymap/keymap_lt.c
src/hci/keymap/keymap_mt.c
src/hci/keymap/keymap_no-latin1.c
src/hci/keymap/keymap_no.c
src/hci/keymap/keymap_pt.c
src/hci/keymap/keymap_se.c
src/hci/keymap/keymap_sg.c
src/util/genkeymap.py

index 4d279171f6282e9abcc57d1744378fb3d3b43b11..6e14395a539f57c0f9cc5dc05359d3d6e68980b6 100644 (file)
@@ -37,10 +37,15 @@ static struct keymap_key al_basic[] = {
 
 /** "al" AltGr remapping */
 static struct keymap_key al_altgr[] = {
+       { 0x21, 0x7e }, /* '!' => '~' */
+       { 0x26, 0x60 }, /* '&' => '`' */
        { 0x30, 0x7e }, /* '0' => '~' */
        { 0x31, 0x7e }, /* '1' => '~' */
        { 0x34, 0x7e }, /* '4' => '~' */
        { 0x37, 0x60 }, /* '7' => '`' */
+       { 0x3a, 0x7e }, /* ':' => '~' */
+       { 0x56, 0x60 }, /* 'V' => '`' */
+       { 0x7c, 0x7e }, /* '|' => '~' */
        { 0, 0 }
 };
 
index 434e3383c08a6afddf64ac11b9b65fdbe54c3a36..55bbfc1a469e6f4a3e0fcbb0817e9e081965cb93 100644 (file)
@@ -33,6 +33,7 @@ static struct keymap_key cf_altgr[] = {
        { 0x27, 0x7b }, /* '\'' => '{' */
        { 0x32, 0x40 }, /* '2' => '@' */
        { 0x3b, 0x7e }, /* ';' => '~' */
+       { 0x5c, 0x7d }, /* '\\' => '}' */
        { 0x60, 0x5c }, /* '`' => '\\' */
        { 0, 0 }
 };
index fb072b11777a875059b9ff58c656663637870c32..08e9638e16a65f57b8433ee28b8e599a3e29638d 100644 (file)
@@ -50,6 +50,9 @@ static struct keymap_key cz_basic[] = {
 
 /** "cz" AltGr remapping */
 static struct keymap_key cz_altgr[] = {
+       { 0x21, 0x7e }, /* '!' => '~' */
+       { 0x24, 0x7e }, /* '$' => '~' */
+       { 0x29, 0x7e }, /* ')' => '~' */
        { 0x2c, 0x3c }, /* ',' => '<' */
        { 0x2e, 0x3e }, /* '.' => '>' */
        { 0x2f, 0x2a }, /* '/' => '*' */
@@ -60,10 +63,15 @@ static struct keymap_key cz_altgr[] = {
        { 0x37, 0x26 }, /* '7' => '&' */
        { 0x38, 0x2a }, /* '8' => '*' */
        { 0x39, 0x7b }, /* '9' => '{' */
+       { 0x3a, 0x7e }, /* ':' => '~' */
        { 0x3b, 0x24 }, /* ';' => '$' */
+       { 0x4b, 0x26 }, /* 'K' => '&' */
+       { 0x58, 0x3e }, /* 'X' => '>' */
+       { 0x5a, 0x3c }, /* 'Z' => '<' */
        { 0x61, 0x7e }, /* 'a' => '~' */
        { 0x62, 0x7b }, /* 'b' => '{' */
        { 0x63, 0x26 }, /* 'c' => '&' */
+       { 0x66, 0x5b }, /* 'f' => '[' */
        { 0x67, 0x5d }, /* 'g' => ']' */
        { 0x6e, 0x7d }, /* 'n' => '}' */
        { 0x76, 0x40 }, /* 'v' => '@' */
index bbd39520f057e9342f04553d9fd656924825397e..ca5e4a9a97c355c6d4b664f54385dd19c7bbec5b 100644 (file)
@@ -47,8 +47,13 @@ static struct keymap_key de_basic[] = {
 static struct keymap_key de_altgr[] = {
        { 0x2d, 0x5c }, /* '-' => '\\' */
        { 0x30, 0x7d }, /* '0' => '}' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
        { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x3b, 0x7e }, /* ';' => '~' */
+       { 0x5d, 0x7e }, /* ']' => '~' */
        { 0x71, 0x40 }, /* 'q' => '@' */
+       { 0x7c, 0x7e }, /* '|' => '~' */
        { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
        { 0, 0 }
 };
index 6d2e60aca94879a45ae9244a7f4d908de56e0d8d..5b229024af044bdc71d433318a9a15f49a0c4178 100644 (file)
@@ -39,7 +39,14 @@ static struct keymap_key dk_basic[] = {
 static struct keymap_key dk_altgr[] = {
        { 0x30, 0x7d }, /* '0' => '}' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x34, 0x24 }, /* '4' => '$' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x3a, 0x7e }, /* ':' => '~' */
        { 0x3d, 0x7c }, /* '=' => '|' */
+       { 0x5c, 0x7e }, /* '\\' => '~' */
+       { 0x5d, 0x7e }, /* ']' => '~' */
        { 0x71, 0x40 }, /* 'q' => '@' */
        { 0, 0 }
 };
index 614ca7b8b4c6da66edd2406906f5772a866ee95a..93d87f2a01be6db05bc0061aa5be0ced8b610318 100644 (file)
@@ -37,14 +37,27 @@ static struct keymap_key es_basic[] = {
 
 /** "es" AltGr remapping */
 static struct keymap_key es_altgr[] = {
+       { 0x22, 0x7b }, /* '"' => '{' */
        { 0x27, 0x7b }, /* '\'' => '{' */
+       { 0x2b, 0x7e }, /* '+' => '~' */
+       { 0x2d, 0x5c }, /* '-' => '\\' */
        { 0x30, 0x7d }, /* '0' => '}' */
+       { 0x31, 0x7c }, /* '1' => '|' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x33, 0x23 }, /* '3' => '#' */
+       { 0x34, 0x7e }, /* '4' => '~' */
        { 0x37, 0x7b }, /* '7' => '{' */
        { 0x38, 0x5b }, /* '8' => '[' */
        { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x3a, 0x7e }, /* ':' => '~' */
+       { 0x3b, 0x7e }, /* ';' => '~' */
+       { 0x3d, 0x7e }, /* '=' => '~' */
        { 0x5c, 0x7d }, /* '\\' => '}' */
+       { 0x60, 0x5c }, /* '`' => '\\' */
        { 0x71, 0x40 }, /* 'q' => '@' */
+       { 0x7c, 0x7e }, /* '|' => '~' */
+       { 0x7e, 0x5c }, /* '~' => '\\' */
+       { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
        { 0, 0 }
 };
 
index f3eb02eabccb5209abe138f5751d95bcb750842b..4d763266f7c310a455b417fcf4e9104d8ee23b41 100644 (file)
@@ -35,8 +35,18 @@ static struct keymap_key et_basic[] = {
 
 /** "et" AltGr remapping */
 static struct keymap_key et_altgr[] = {
+       { 0x26, 0x7b }, /* '&' => '{' */
+       { 0x28, 0x5d }, /* '(' => ']' */
+       { 0x29, 0x7d }, /* ')' => '}' */
+       { 0x2a, 0x5b }, /* '*' => '[' */
        { 0x2d, 0x5c }, /* '-' => '\\' */
+       { 0x30, 0x7d }, /* '0' => '}' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x34, 0x24 }, /* '4' => '$' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x5f, 0x5c }, /* '_' => '\\' */
        { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
        { 0, 0 }
 };
index 622f06252f905229b83a0db55981e16c0a7ff0a8..ac69813e8ac8d69d014a0b6efaadbea0dd9d4e38 100644 (file)
@@ -38,6 +38,12 @@ static struct keymap_key fi_altgr[] = {
        { 0x2d, 0x5c }, /* '-' => '\\' */
        { 0x30, 0x7d }, /* '0' => '}' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x34, 0x24 }, /* '4' => '$' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x49, 0x7c }, /* 'I' => '|' */
+       { 0x5d, 0x7e }, /* ']' => '~' */
        { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
        { 0, 0 }
 };
index c002bf95a57dcdc97c356ec6a6a919be7ed56540..ad797f876a90a1ec653c4df31676832645471751 100644 (file)
@@ -68,9 +68,15 @@ static struct keymap_key fr_altgr[] = {
        { 0x2d, 0x5d }, /* '-' => ']' */
        { 0x30, 0x40 }, /* '0' => '@' */
        { 0x33, 0x23 }, /* '3' => '#' */
+       { 0x34, 0x7b }, /* '4' => '{' */
        { 0x35, 0x5b }, /* '5' => '[' */
+       { 0x36, 0x7c }, /* '6' => '|' */
+       { 0x37, 0x60 }, /* '7' => '`' */
        { 0x38, 0x5c }, /* '8' => '\\' */
+       { 0x3d, 0x7d }, /* '=' => '}' */
+       { 0x5c, 0x60 }, /* '\\' => '`' */
        { 0x61, 0x40 }, /* 'a' => '@' */
+       { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
        { 0, 0 }
 };
 
index 8f2d70aac7d05e22077793d768fd06cd89401949..d64baaebf5b1245ea674ff94715119af755c8f97 100644 (file)
@@ -37,18 +37,36 @@ static struct keymap_key hu_basic[] = {
 
 /** "hu" AltGr remapping */
 static struct keymap_key hu_altgr[] = {
+       { 0x21, 0x7e }, /* '!' => '~' */
+       { 0x23, 0x5e }, /* '#' => '^' */
+       { 0x26, 0x60 }, /* '&' => '`' */
+       { 0x2c, 0x3b }, /* ',' => ';' */
        { 0x2e, 0x3e }, /* '.' => '>' */
        { 0x2f, 0x2a }, /* '/' => '*' */
+       { 0x30, 0x7e }, /* '0' => '~' */
+       { 0x31, 0x7e }, /* '1' => '~' */
        { 0x32, 0x5e }, /* '2' => '^' */
        { 0x33, 0x5e }, /* '3' => '^' */
+       { 0x34, 0x7e }, /* '4' => '~' */
        { 0x37, 0x60 }, /* '7' => '`' */
        { 0x3b, 0x24 }, /* ';' => '$' */
+       { 0x4b, 0x26 }, /* 'K' => '&' */
+       { 0x58, 0x3e }, /* 'X' => '>' */
+       { 0x5a, 0x3c }, /* 'Z' => '<' */
+       { 0x62, 0x7b }, /* 'b' => '{' */
        { 0x63, 0x26 }, /* 'c' => '&' */
+       { 0x66, 0x5b }, /* 'f' => '[' */
+       { 0x67, 0x5d }, /* 'g' => ']' */
        { 0x6d, 0x3c }, /* 'm' => '<' */
+       { 0x6e, 0x7d }, /* 'n' => '}' */
+       { 0x71, 0x5c }, /* 'q' => '\\' */
        { 0x76, 0x40 }, /* 'v' => '@' */
+       { 0x77, 0x7c }, /* 'w' => '|' */
        { 0x78, 0x23 }, /* 'x' => '#' */
        { 0x7a, 0x3e }, /* 'z' => '>' */
+       { 0x7c, 0x7e }, /* '|' => '~' */
        { 0xdc, 0x3c }, /* Pseudo-'\\' => '<' */
+       { 0xfc, 0x3e }, /* Pseudo-'|' => '>' */
        { 0, 0 }
 };
 
index a55dafe6a0455abc50919483aa0ea044e4e8d924..2511bb7910bf65176fd3c30f6084d0b4dbc57d96 100644 (file)
@@ -37,13 +37,19 @@ static struct keymap_key it_basic[] = {
 
 /** "it" AltGr remapping */
 static struct keymap_key it_altgr[] = {
+       { 0x23, 0x7e }, /* '#' => '~' */
+       { 0x27, 0x23 }, /* '\'' => '#' */
        { 0x2d, 0x60 }, /* '-' => '`' */
        { 0x30, 0x7d }, /* '0' => '}' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
        { 0x39, 0x5d }, /* '9' => ']' */
        { 0x3b, 0x40 }, /* ';' => '@' */
        { 0x3d, 0x7e }, /* '=' => '~' */
+       { 0x40, 0x7e }, /* '@' => '~' */
        { 0x5c, 0x60 }, /* '\\' => '`' */
        { 0x71, 0x40 }, /* 'q' => '@' */
+       { 0x7c, 0x7e }, /* '|' => '~' */
        { 0, 0 }
 };
 
index 5d6ee5a8cc748529a3f78017f9ba661e05e349a0..a237b1d6200ede98496d0629c2a3be7b397e1286 100644 (file)
@@ -17,6 +17,10 @@ static struct keymap_key lt_basic[] = {
 
 /** "lt" AltGr remapping */
 static struct keymap_key lt_altgr[] = {
+       { 0x22, 0x5e }, /* '"' => '^' */
+       { 0x27, 0x5e }, /* '\'' => '^' */
+       { 0x4b, 0x26 }, /* 'K' => '&' */
+       { 0x71, 0x40 }, /* 'q' => '@' */
        { 0, 0 }
 };
 
index 0a9a110b061a087fac95f0e5f43156695169ff5d..a95c5b4e84b22de29d51b46b015c71e839c34d84 100644 (file)
@@ -22,6 +22,11 @@ static struct keymap_key mt_basic[] = {
 
 /** "mt" AltGr remapping */
 static struct keymap_key mt_altgr[] = {
+       { 0x30, 0x7d }, /* '0' => '}' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x5c, 0x60 }, /* '\\' => '`' */
        { 0, 0 }
 };
 
index 63fe8554823370cd39f2a551241f9c1969352432..1f4cc38d336b1bf35677863313432757f12a4e00 100644 (file)
@@ -39,10 +39,15 @@ static struct keymap_key no_latin1_basic[] = {
 
 /** "no-latin1" AltGr remapping */
 static struct keymap_key no_latin1_altgr[] = {
+       { 0x22, 0x5b }, /* '"' => '[' */
+       { 0x27, 0x7b }, /* '\'' => '{' */
        { 0x30, 0x7d }, /* '0' => '}' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
        { 0x39, 0x5d }, /* '9' => ']' */
        { 0x5b, 0x7d }, /* '[' => '}' */
+       { 0x7b, 0x5d }, /* '{' => ']' */
        { 0, 0 }
 };
 
index 4b2f7268ebb1eda1d974d6d925f4f9b404931629..239e3aea5bd92e96532955cd76ca80207d55c36a 100644 (file)
@@ -41,6 +41,13 @@ static struct keymap_key no_basic[] = {
 static struct keymap_key no_altgr[] = {
        { 0x30, 0x7d }, /* '0' => '}' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x34, 0x24 }, /* '4' => '$' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x3a, 0x7e }, /* ':' => '~' */
+       { 0x5c, 0x7e }, /* '\\' => '~' */
+       { 0x5d, 0x7e }, /* ']' => '~' */
        { 0x71, 0x40 }, /* 'q' => '@' */
        { 0, 0 }
 };
index f294e9563cd6094de8e44a58bb66f4e945e51725..75bf565ce20a2b13e9c778f72a061339993ee7dc 100644 (file)
@@ -44,6 +44,7 @@ static struct keymap_key pt_altgr[] = {
        { 0x32, 0x40 }, /* '2' => '@' */
        { 0x37, 0x7b }, /* '7' => '{' */
        { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
        { 0x71, 0x40 }, /* 'q' => '@' */
        { 0, 0 }
 };
index 6ca990444d0a24914b93c478b5fa025fb414b01c..9c6cf64a407e5ea158a41ad16b0efb4249811247 100644 (file)
@@ -40,6 +40,11 @@ static struct keymap_key se_altgr[] = {
        { 0x2d, 0x5c }, /* '-' => '\\' */
        { 0x30, 0x7d }, /* '0' => '}' */
        { 0x32, 0x40 }, /* '2' => '@' */
+       { 0x34, 0x24 }, /* '4' => '$' */
+       { 0x37, 0x7b }, /* '7' => '{' */
+       { 0x38, 0x5b }, /* '8' => '[' */
+       { 0x39, 0x5d }, /* '9' => ']' */
+       { 0x5d, 0x7e }, /* ']' => '~' */
        { 0x71, 0x40 }, /* 'q' => '@' */
        { 0xdc, 0x7c }, /* Pseudo-'\\' => '|' */
        { 0, 0 }
index 9a6db9cb4165bed36ac9c842f222954351fb8c16..2afe59c615d53d818582ce9acb3a0c7e1c3cf425 100644 (file)
@@ -45,9 +45,11 @@ static struct keymap_key sg_basic[] = {
 
 /** "sg" AltGr remapping */
 static struct keymap_key sg_altgr[] = {
+       { 0x27, 0x7b }, /* '\'' => '{' */
        { 0x32, 0x40 }, /* '2' => '@' */
        { 0x33, 0x23 }, /* '3' => '#' */
        { 0x37, 0x7c }, /* '7' => '|' */
+       { 0x3d, 0x7e }, /* '=' => '~' */
        { 0x5c, 0x7d }, /* '\\' => '}' */
        { 0, 0 }
 };
index 8df949612b1984657c595f502cbb4438d5c1fa18..632f71edac896400690c6bcd6cc107f5fadc6855 100755 (executable)
@@ -33,6 +33,10 @@ import textwrap
 from typing import ClassVar, Optional
 
 
+BACKSPACE = chr(0x7f)
+"""Backspace character"""
+
+
 class KeyType(IntEnum):
     """Key types"""
 
@@ -174,7 +178,7 @@ class KeyLayout(UserDict[KeyModifiers, Sequence[Key]]):
             KeyModifiers.NONE: [(KEY_NON_US, ord('\\'))],
             KeyModifiers.SHIFT: [(KEY_NON_US, ord('|'))],
             # Treat Ctrl-Backspace as producing Backspace rather than Ctrl-H
-            KeyModifiers.CTRL: [(KEY_BACKSPACE, 0x7f)],
+            KeyModifiers.CTRL: [(KEY_BACKSPACE, ord(BACKSPACE))],
         },
         'il': {
             # Redefine some otherwise unreachable ASCII characters
@@ -200,11 +204,6 @@ class KeyLayout(UserDict[KeyModifiers, Sequence[Key]]):
         """Basic shifted keyboard layout"""
         return self[KeyModifiers.SHIFT]
 
-    @property
-    def altgr(self):
-        """AltGr keyboard layout"""
-        return self.get(KeyModifiers.ALTGR, self.unshifted)
-
     @classmethod
     def load(cls, name: str) -> KeyLayout:
         """Load keymap using 'loadkeys -b'"""
@@ -281,7 +280,7 @@ class BiosKeyLayout(KeyLayout):
         return inverse
 
 
-class KeymapKeys(UserDict[str, str]):
+class KeymapKeys(UserDict[str, Optional[str]]):
     """An ASCII character remapping"""
 
     @classmethod
@@ -312,7 +311,8 @@ class KeymapKeys(UserDict[str, str]):
                 self.ascii_name(source), self.ascii_name(target)
             )
             for source, target in self.items()
-            if ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target)
+            if target
+            and ord(source) & ~BiosKeyLayout.KEY_PSEUDO != ord(target)
         ) + '\t{ 0, 0 }\n}'
 
 
@@ -335,13 +335,12 @@ class Keymap:
         # Construct raw mapping from source ASCII to target ASCII
         raw = {source: self.target[key.modifiers][key.keycode].ascii
                for source, key in self.source.inverse.items()}
-        # Eliminate any null mappings, mappings that attempt to remap
-        # the backspace key, or identity mappings
+        # Eliminate any identity mappings, or mappings that attempt to
+        # remap the backspace key
         table = {source: target for source, target in raw.items()
-                 if target
-                 and ord(source) != 0x7f
-                 and ord(target) != 0x7f
-                 and source != target}
+                 if source != target
+                 and source != BACKSPACE
+                 and target != BACKSPACE}
         # Recursively delete any mappings that would produce
         # unreachable alphanumerics (e.g. the "il" keymap, which maps
         # away the whole lower-case alphabet)
@@ -354,8 +353,8 @@ class Keymap:
         # Sanity check: ensure that all numerics are reachable using
         # the same shift state
         digits = '1234567890'
-        unshifted = ''.join(table.get(x, x) for x in '1234567890')
-        shifted = ''.join(table.get(x, x) for x in '!@#$%^&*()')
+        unshifted = ''.join(table.get(x) or x for x in '1234567890')
+        shifted = ''.join(table.get(x) or x for x in '!@#$%^&*()')
         if digits not in (shifted, unshifted):
             raise ValueError("Inconsistent numeric remapping %s / %s" %
                              (unshifted, shifted))
@@ -365,21 +364,22 @@ class Keymap:
     def altgr(self) -> KeymapKeys:
         """AltGr remapping table"""
         # Construct raw mapping from source ASCII to target ASCII
-        raw = {source: self.target.altgr[key.keycode].ascii
-               for source, key in self.source.inverse.items()
-               if key.modifiers == KeyModifiers.NONE}
+        raw = {
+            source:
+            self.target.get((key.modifiers | KeyModifiers.ALTGR),
+                            self.target[key.modifiers])[key.keycode].ascii
+            for source, key in self.source.inverse.items()
+        }
         # Identify printable keys that are unreachable via the basic map
         basic = self.basic
         unmapped = set(x for x in basic.keys()
                        if x.isascii() and x.isprintable())
         remapped = set(basic.values())
         unreachable = unmapped - remapped
-        # Eliminate any null mappings, mappings for unprintable
-        # characters, or mappings for characters that are reachable
-        # via the basic map
+        # Eliminate any mappings for unprintable characters, or
+        # mappings for characters that are reachable via the basic map
         table = {source: target for source, target in raw.items()
                  if source.isprintable()
-                 and target
                  and target in unreachable}
         # Check that all characters are now reachable
         unreachable -= set(table.values())